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 ...
随机推荐
- SSH免密码(日志三)
上一篇:JDK安装以及安装过程中出现的问题(日志二) 原理,就是RSA加密,含有公钥和私钥,具体言之,用公钥来确认请求人是否是私钥的持有人. 1, 2, 3, 4, ssh免密码过程中遇到的问题:需要 ...
- JS 基本数据类型和引用数据类型
本文章已收录于: .embody { padding: 10px 10px 10px; margin: 0 -20px; border-bottom: solid 1px #ededed } .e ...
- zoj1654 Place the Robots 二分图最大匹配
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=654 将每一行的包含空地的区域编号 再将每一列的包含空地的区域编号 然 ...
- 使用MyEclipse生成实体类和Hibernate映射文件
1.打开MyEclipse DataBase Explorer. 如上图,点击图中2便可切换到MyEclipse DataBase Explorer,若没有该图标,则点击图中1,便可选择MyEclip ...
- linux vi 报错 E37: No write since last change (add ! to override)
用 vi 命令编辑文本文件,没有文件写入权限的时候会报这个错.:q :wq 怎么都不能退出. 这时只需 ctrl+z 即可,或者在退出命令后加 ! 忽略提示 :q!
- JAVA进程占用CPU分析
在一次生产环境中,服务器负载报警,SSH登录上看到CPU占用很高. 1.执行top命令,看到进程号为9737的进程持续占用CPU 2.怀疑是否是进程配置的内存不够了,引发了fullGC导致CPU占用高 ...
- Ubuntu14.04安装samba
Ubuntu14.04安装samba 按照惯例,首先介绍Samba.Samba是在Linux系统上实现的SMB(Server Messages Block,信息服务块)协议的一款免费软件.它实现在局域 ...
- AVL树(平衡二叉查找树)
首先要说AVL树,我们就必须先说二叉查找树,先介绍二叉查找树的一些特性,然后我们再来说平衡树的一些特性,结合这些特性,然后来介绍AVL树. 一.二叉查找树 1.二叉树查找树的相关特征定义 二叉树查找树 ...
- 对于php内存释放问题
大家在使用PhpExcel类时,当打开一个比较大的excel数据文档,会出现Fatalerror: Allowed memorysize of 67108864 bytes exhausted (tr ...
- day_1_登录接口
#/usr/bin/env python3# -*- coding: utf-8 -*-##This is an account login authentication##Version 1.0## ...