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/

Adapter模式进行代码重构的更多相关文章

  1. 代码重构:用工厂+策略模式优化冗余的if else代码块

    最近在工作中优化了一段冗余的if else代码块,感觉对设计模式的理解和运用很有帮助,所以分享出来.鉴于原代码会涉及到公司的隐私,因此就不贴出来了.下面以更加通俗易懂的案例来解析. 假如写一个针对员工 ...

  2. 代码重构:用工厂+策略模式优化过多的if else代码块

    最近在工作中优化了一段冗余的if else代码块,感觉对设计模式的理解和运用很有帮助,所以分享出来.鉴于原代码会涉及到公司的隐私,因此就不贴出来了.下面以更加通俗易懂的案例来解析. 假如写一个针对员工 ...

  3. 设计模式C++描述----06.适配器(Adapter)模式

    一. 定义 适配器模式将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. Adapter 模式的两种类别:类模式和对象模式. 二. 举例说明 实际中 ...

  4. Android Studio在代码重构中的妙用

    代码重构几乎是每个程序员在软件开发中必须要不断去做的事情,以此来不断提高代码的质量.Android Stido(以下简称AS)以其强大的功能,成为当下Android开发工程师最受欢迎的开发工具,也是A ...

  5. .NET应用架构设计—表模块模式与事务脚本模式的代码编写

    阅读目录: 1.背景介绍 2.简单介绍表模块模式.事务脚本模式 3.正确的编写表模块模式.事务脚本模式的代码 4.总结 1.背景介绍 要想正确的设计系统架构就必须能正确的搞懂每个架构模式的用意,而不是 ...

  6. 代码重构 & 常用设计模式

    代码重构 重构目的 相同的代码最好只出现一次 主次方法 主方法 只包含实现完整逻辑的子方法 思维清楚,便于阅读 次方法 实现具体逻辑功能 测试通过后,后续几乎不用维护 重构的步骤 1  新建一个方法 ...

  7. Abstract Server模式,Adapter模式和Bridge模式

    简易的台灯 Abstract Server模式 谁拥有接口. 接口属于它的客户,而不是它的派生类. 接口和客户之间的逻辑关系,强于接口和其派生类的逻辑关系. 逻辑关系和实体关系的强度是不一致的.在实体 ...

  8. 设计模式--适配器(Adapter)模式

    今天学习另一个设计模式,适配器(Adapter)模式,这是一个共同方向,但有特殊要求,就应用到此设计模式.写到这里,想起很久以前,有写过一篇<ASP.NET的适配器设计模式(Adapter)&g ...

  9. Adapter模式

    Adapter模式主要用于将一个类的接口转换为另外一个接口,通常情况下再不改变原有体系的条件下应对新的需求变化,通过引入新的适配器类来完成对既存体系的扩展和改造.实现方式主要包括: 1.类的Adapt ...

随机推荐

  1. 用Python设计一个经典小游戏

    这是关于Python的第9篇文章,介绍如何用Python设计一个经典小游戏:猜大小. 在这个游戏中,将用到前面我介绍过的所有内容:变量的使用.参数传递.函数设计.条件控制和循环等,做个整体的总结和复习 ...

  2. Java学习笔记——封装、继承和多态

    先说说封装: 用new 一条狗来举个例子: public class Dog { //私有化字段 private String name; private int age; //无参构造 Dog(){ ...

  3. MySQL数据库操作常用命令

    MySQL数据库操作常用命令DOS连接数据库1.安装MySQL配置好环境2.运行cmd命令net start mysql3.找到mysql文件根目录输入命令mysql -h localhost -u ...

  4. Angular2 关于*ngFor 嵌套循环

    在项目开发中拿到的数据是这样的,要循环遍历出来.可是在ng2中好像不能直接遍历Object datas: any = [ { num: 1, date: "2017-04-12", ...

  5. 港交所OMD-C对接笔记

    工作中需要对接港交所OMD-C的Standard版行情,现在把一些知识点做个笔记,供以后查阅. 「香港交易所领航星」巿场数据平台-证券市场(HKEX Orion Market Data Platfor ...

  6. idea 控制台输出 中文乱码 解决方法

    使用intellij idea 14.1时,console 会输出中文乱码.下面分两种情况解决这种问题:一种是maven构建项目.一种是tomcat(不以maven构建)构建项目. 1.tomcat输 ...

  7. javaWeb学习总结(3)- Servlet总结(servlet的主要接口、类)

    Servlet总结01——servlet的主要接口.类 (一)servlet类 Servlet主要类.接口的结构如下图所示: 要编写一个Servlet需要实现javax.servlet.Servlet ...

  8. JVM垃圾收集算法

    JVM垃圾收集 1. 判断对象是否存活 引用计数算法 对象添加一个引用计数器,每个地方引用它,计数器值加+1:当引用失效,计算器值减1:任何时刻计数器为0的对象不可能被使用.引用计数算法实现简单,高效 ...

  9. MySql学习笔记(五) —— 存储过程

    存储过程是MySql 5支持的特性,它是一组为了完成特定功能的SQL语句集,经过编译之后存储在数据库中,当需要使用该组SQL语句时用户只需要通过指定储存过程的名字并给定参数就可以调用执行它了,简而言之 ...

  10. 深入理解C#中的String

    关于C#中的类型 在C#中类型分为值类型和引用类型,引用类型和值类型都继承自System.Object类,几乎所有的引用类型都直接从System.Object继承,而值类型具体一点则继承System. ...