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/
Adapter模式进行代码重构的更多相关文章
- 代码重构:用工厂+策略模式优化冗余的if else代码块
最近在工作中优化了一段冗余的if else代码块,感觉对设计模式的理解和运用很有帮助,所以分享出来.鉴于原代码会涉及到公司的隐私,因此就不贴出来了.下面以更加通俗易懂的案例来解析. 假如写一个针对员工 ...
- 代码重构:用工厂+策略模式优化过多的if else代码块
最近在工作中优化了一段冗余的if else代码块,感觉对设计模式的理解和运用很有帮助,所以分享出来.鉴于原代码会涉及到公司的隐私,因此就不贴出来了.下面以更加通俗易懂的案例来解析. 假如写一个针对员工 ...
- 设计模式C++描述----06.适配器(Adapter)模式
一. 定义 适配器模式将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. Adapter 模式的两种类别:类模式和对象模式. 二. 举例说明 实际中 ...
- Android Studio在代码重构中的妙用
代码重构几乎是每个程序员在软件开发中必须要不断去做的事情,以此来不断提高代码的质量.Android Stido(以下简称AS)以其强大的功能,成为当下Android开发工程师最受欢迎的开发工具,也是A ...
- .NET应用架构设计—表模块模式与事务脚本模式的代码编写
阅读目录: 1.背景介绍 2.简单介绍表模块模式.事务脚本模式 3.正确的编写表模块模式.事务脚本模式的代码 4.总结 1.背景介绍 要想正确的设计系统架构就必须能正确的搞懂每个架构模式的用意,而不是 ...
- 代码重构 & 常用设计模式
代码重构 重构目的 相同的代码最好只出现一次 主次方法 主方法 只包含实现完整逻辑的子方法 思维清楚,便于阅读 次方法 实现具体逻辑功能 测试通过后,后续几乎不用维护 重构的步骤 1 新建一个方法 ...
- Abstract Server模式,Adapter模式和Bridge模式
简易的台灯 Abstract Server模式 谁拥有接口. 接口属于它的客户,而不是它的派生类. 接口和客户之间的逻辑关系,强于接口和其派生类的逻辑关系. 逻辑关系和实体关系的强度是不一致的.在实体 ...
- 设计模式--适配器(Adapter)模式
今天学习另一个设计模式,适配器(Adapter)模式,这是一个共同方向,但有特殊要求,就应用到此设计模式.写到这里,想起很久以前,有写过一篇<ASP.NET的适配器设计模式(Adapter)&g ...
- Adapter模式
Adapter模式主要用于将一个类的接口转换为另外一个接口,通常情况下再不改变原有体系的条件下应对新的需求变化,通过引入新的适配器类来完成对既存体系的扩展和改造.实现方式主要包括: 1.类的Adapt ...
随机推荐
- [转载]PHP检测一个元素是否存在于数组中
- redis中键的生存时间(expire)
1.redis中可以使用expire命令设置一个键的生存时间,到时间后redis会自动删除它 expire 设置生存时间(单位/秒) pexpire 设置生存时间(单位/毫秒) ttl/pttl 查看 ...
- 关于Ubuntu的ssh免密登录
1.打开"终端窗口",输入"sudo apt-get update"-->回车-->"输入当前登录用户的管理员密码"--> ...
- NancyFx 2.0的开源框架的使用-CustomModule(自定义模块)
NancyFx框架的自定义模块 新建一个空的Web项目 然后通过NuGet库安装下面的包 Nancy Nancy.Hosting.Aspnet 然后添加Models,Module,Views三个文件夹 ...
- Linux Network Management
Linux网络管理 (YouTube视频教程) ISO/OSI七层模型 ISO: The International Organization for Standardization 国际标准化组织 ...
- Hibernate中遇到的一个Exception
做项目的时候遇到一个很头疼的报错:Illegal attempt to associate a collection with two opensessions 出错原因: 一个Object Ver ...
- 细说C#中的系列化与反系列化的基本原理和过程
虽然我们平时都使用第三方库来进行系列化和反系列化,用起来也很方便,但至少得明白系列化与反系列化的基本原理. 注意:从.NET Framework 2.0 开始,系列化格式化器类SoapFormatte ...
- STM32串口控制步进电机(原创)
用的42步进电机: 厂家可能不一样,两项四线步进电机,里面有两个线圈.在电机什么电都没有接的情况下,用万用表测量四个管脚:两两短接(或者阻值很小)的为一组,可以分别接A+,a-剩余接B+,B-;顺序可 ...
- 006开源O/R映射框架内容回顾
Hibernate是一个O/R映射框架(也称为ORM) 从ORM词来看,O---Object(对象模型):R--- Relational(关联模型),可以做对象和关联的一种映射,当然这只是部分功能,一 ...
- CentOS7下配置网络yum源(附带下载地址)
一.查看外网是否通畅 配置网络yum源(需要保证外网开通,我这里是使用网易163提供开源镜像站) 二.下载repo文件 cd /etc/yum.repos.dwget http://mirrors.1 ...