zoukankan      html  css  js  c++  java
  • Adapter模式进行代码重构

    Adapter(适配器)模式主要是将一个类的某个接口转换成一个兼容的接口。

    下面是实现一个商品检索的示例
    【Bad Code】

     public class Product
     {
     }
    
     public class ProductRepository
     {
         public IList<Product> GetAllProductsIn(int categoryId)
         {
             IList<Product> products = new List<Product>();
             //从数据库中读取Product数据
             return products;
         }
     }
    
     public class ProductService
     {
         private ProductRepository _productRepository;
    
         public ProductService()
         {
             _productRepository = new ProductRepository();
         }
    
         public IList<Product> GetAllProductsIn(int categoryId)
         {
             IList<Product> products;
             string storegeKey = string.Format("products_in_category_id_{0}", categoryId);
             products = (List<Product>)HttpContext.Current.Cache.Get(storegeKey);
             if (products == null)
             {
                 products = _productRepository.GetAllProductsIn(categoryId);
                 //将商品列表保存到缓存中
                 HttpContext.Current.Cache.Insert(storegeKey, products);
             }
             return products;
         }
     }
    

    这段代码中的主要问题:

    • ProductService类强依赖ProductRepository类。
    • 强依赖于HttpContext缓存。

    【Code Refactoring】

     public class Product
     {
     }
    
     public class ProductRepository : IProductRepository
     {
         public IList<Product> GetAllProductsIn(int categoryId)
         {
             IList<Product> products = new List<Product>();
             //从数据库中读取Product数据
             return products;
         }
     }
    
     public class ProductService
     {
         //private ProductRepository _productRepository;
         //依赖抽象,而不是依赖具体
         private IProductRepository _productRepository;
         private ICacheStorage _cacheStorage;
    
         //通过构造函数注入,由客户端代码去实现IProductRepository、ICacheStorage接口
         public ProductService(IProductRepository productRepository, ICacheStorage cacheStorage)
         {
             _productRepository = productRepository;
             _cacheStorage = cacheStorage;
         }
    
         public IList<Product> GetAllProductsIn(int categoryId)
         {
             IList<Product> products;
             string storegeKey = string.Format("products_in_category_id_{0}", categoryId);
    
             //  products = (List<Product>)HttpContext.Current.Cache.Get(storegeKey);
             //不再依赖HttpContext缓存
             products = _cacheStorage.Retrieve<List<Product>>(storegeKey);
    
             if (products == null)
             {
                 products = _productRepository.GetAllProductsIn(categoryId);
                 //将商品列表保存到缓存中
                 //HttpContext.Current.Cache.Insert(storegeKey, products);
    
                 _cacheStorage.Store(storegeKey, products);
             }
             return products;
         }
     }
    
     public interface IProductRepository
     {
         IList<Product> GetAllProductsIn(int categoryId);
     }
    
     public interface ICacheStorage
     {
         void Remove(string key);
         void Store(string key, object data);
         //检索
         T Retrieve<T>(string key);
     }
    
     /// <summary>
     /// HttpContext缓存实现
     /// </summary>
     public class HttpContextCacheAdapter : ICacheStorage
     {
         public void Remove(string key)
         {
             HttpContext.Current.Cache.Remove(key);
         }
    
         public T Retrieve<T>(string key)
         {
             T itemStored = (T)HttpContext.Current.Cache.Get(key);
             if (itemStored == null)
                 itemStored = default(T);
             return itemStored;
         }
    
         public void Store(string key, object data)
         {
             HttpContext.Current.Cache.Insert(key, data);
         }
     }
    

    Adapter模式的目的就是提供一个兼容的接口,比如上面的缓存机制改为Memcached,只需要增加一个MemcachedCacheAdapter的实现,而不用去该ProductService类,也就是达到了对类扩展开放,对修改封闭的原则。

    ASP.NET设计模式:https://book.douban.com/subject/6958404/

  • 相关阅读:
    js表单验证
    i利用图片按钮 和 input type="image" 为背景提交表单
    php 时间转换
    select 响应时间 js
    浏览器兼容
    选修课程的级联。
    时间显示的位置
    广告飘动
    C++--引用
    ubuntu中可以ping通IP地址但是ping不通域名的问题(www.baidu.com)
  • 原文地址:https://www.cnblogs.com/yangsofter/p/Adapter.html
Copyright © 2011-2022 走看看