• 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

     

     

  • 相关阅读:
    C# winform 打包成安装程序(exe)
    gitHub----【Mac】sourcetree连接github,报错:fatal:Authentication failed for'https://git…。或提示password required 解决方案
    python3-----往一个字符串中循环添加数据
    python3.8----从多层嵌套Json中解析所需要的值
    记录一些工作知识
    【转】彻底搞懂 async & defer
    【转】判断JS数据类型的四种方法
    动态表单设计
    封装,继承,多态
    语义化版本
  • 原文地址:https://www.cnblogs.com/keanuyaoo/p/3270936.html
Copyright © 2020-2023  润新知