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)