Asp.Net Design Pattern Studynotes -- Part1

来源:互联网 发布:80端口提供什么服务 编辑:程序博客网 时间:2024/06/09 18:26

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

 

 

原创粉丝点击