Asp.Net Design Pattern Studynotes -- Part1

Asp.Net Design Pattern Studynotes -- Part1

let's start with an exampleto entry amazing OO world !

let's saynow we need to implement a small feature which need :

an entityclass: Product

businesslogic : List<Product>GetProductBy(Function<Product,bool> where);

Service : List<Product> GetProductBy(Function<Product,bool>where);

1st Version

Entity:

public classProduct{}


Logic:

public classProductRepositoryV1
    {
 
       public List<Product>GetProductBy(Func<Product,bool> where )
       {
           var products = newList<Product>();
           returnproducts.Where(where).ToList();
       }
    }


service:

classProductServiceV1
    {
        private ProductRepositoryV1 _productRespository;
        private List<Product>_cacheProduct ;
 
        public ProductServiceV1()
        {
            _productRespository = newProductRepositoryV1(); //1.instant
            _cacheProduct = newList<Product>();
        }
 
        public List<Product>GetProductListBy(Func<Product,bool> where)
        {
            var productInCache =_cacheProduct.Where(where);//3.in couple with BL
            if (!productInCache.Any())
            {
                var products =_productRespository.GetProductBy(where);
               _cacheProduct.AddRange(products); //2.also care about how to cache
                return products;
            }
            return productInCache.ToList();
        }
 
    }


But we cansee the deficiencies :

For 1stVersion (Original Version):

1.productServiceis in couple with ProductRepository .once productRespository changed method signature, service have to change code.

solution: depend onabstract but not on concrete implementation

2.code is untestable .which need data base ready , but if data base can not connect ,meaning can not be tested.

solution: decoupleservice from business class

3.do multiple things .

a. cache thedata ,b. provice service .c. instance the repository object .

solution : do only one thing .

ok, nowlet's fix it !

2nd version :

Entity: same with above .

business:

interface IProductRespository//added interface fordependency inversion
    {
        List<Product>GetProductBy(Func<Product, bool> where);
    }
 class ProductRespositoryV2:IProductRespository
    {
        public List<Product>GetProductBy(Func<Product, bool> where)
        {
            var products = newList<Product>();
            returnproducts.Where(where).ToList();
        }
    }

Service :

class ProductServiceV2
    {
         private IProductRespository _productRespository;
        private List<Product>_cacheProduct ;
 
        public ProductServiceV2(IProductRespositorypr)
        {
            _productRespository = pr;
            _cacheProduct = newList<Product>();
        }
 
        public List<Product> GetProductListBy(Func<Product,bool> where)
        {
            var productInCache =_cacheProduct.Where(where);
            if (!productInCache.Any())
            {
                var products =_productRespository.GetProductBy(where);
               _cacheProduct.AddRange(products);
                return products;
            }
            return productInCache.ToList();
        }
    }
 
 

For 2ndVersion (Applydependency inversion + Dependency injection):

.still do multiple things:

a.still need to care about how to store . b. provide service

solution :put the responsibility of cache storage into another class,let service only depends on interface (IStorage)

3rd Version(Adapter pattern + Dependency inversion)

Entity :same with above .

business:

interface IProductRespository
    {
        List<Product> GetProductBy(Func<Product, bool> where);
    }
interface IStorage
    {
        void Add(IEnumerable<Product>products);
        IEnumerable<Product> Get(Func<Product, bool> where);
    }
 
class MemoryStorage:IStorage // Take the responsibility ofCache
    {
        private List<Product>_cacheProduct;
        public MemoryStorage()
        {
            _cacheProduct = newList<Product>();
        }
        public void Add(IEnumerable<Product> products)
        {
           _cacheProduct.AddRange(products);           
        }
 
        public IEnumerable<Product> Get(Func<Product, bool> where)
        {
            return _cacheProduct.Where(where);
        }
    }
 
class  ProductRespositoryV3:IProductRespository
    {
        public List<Product> GetProductBy(Func<Product, bool> where)
        {
            var products = new List<Product>();
            return products.Where(where).ToList();
        }
    }


Service:

class ProductServiceV3
    {
      // only dependson  abstract
         private IProductRespository_productRespository;
        private IStorage_cache;
 
  public ProductServiceV3(IProductRespository pr, IStorage storage)
        {
//new objalso do not care
            _productRespository = pr;
            _cache = storage;
        }
        public List<Product> GetProductListBy(Func<Product,bool> where)
        {
            var productInCache = _cache.Get(where);
            if (!productInCache.Any())
            {
                var products = _productRespository.GetProductBy(where);
                _cache.Add(products);
                return products;
            }
            return productInCache.ToList();
        }
    }


We Can see ,

1.Service only depends on Interface which is abstract(no more need to care about how to cache the data) ,

2.and for Service, storage and respository class only do one thing

3.for service ,respository ,storage all can be UT .

Whenever weare coding any class,always remember these 3 things :

1.only do one thing

2.depends only on abstract

3.always can be tested

你可能感兴趣的:(design pattern)