23种设计模式之适配器模式(Adapter Pattern)
适配
即在不改变原有实现的基础上,将原先不兼容的接口转换为兼容的接口。
例如:二转换为三箱插头,将高电压转换为低电压等。
动机(Motivate):
在软件系统中,由于应用环境的变化,常常需要将“一些现存的对象”放在新的环境中应用,但是新环境要求的接口是这些现存对象所不满足的。
那么如何应对这种“迁移的变化”?如何既能利用现有对象的良好实现,同时又能满足新的应用环境所要求的接口?这就是本文要说的Adapter 模式。
意图(Intent):
将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
-------《设计模式》GOF
抽象的 UML 类图
4 种角色:Adaptee(被适配),Adapter(适配者),Client(使用场景),Target(目标对象)。
Adaptee(被适配):不是 -er 结尾的哦,之前的 Portal(入口)类作为被适配者。
Adapter(适配者):作为 Adaptee 和 Target 的媒介,进行调节。
Client(使用场景):一个调用的入口,以 Main() 作为入口函数。
Target(目标对象):调节(适配)后的输出,之前的 IOutput 接口和 Export 类都是作为 Target 对象。

图:类适配器(使用继承)

图:对象适配器(使用委托)
/// <summary>
/// 数据访问接口
/// </summary>
public interface IHelper
{
void Add<T>();
void Delete<T>();
void Update<T>();
void Query<T>();
}
public class MysqlHelper : IHelper
{
public void Add<T>()
{
Console.WriteLine("This is {0} Add", this.GetType().Name);
}
public void Delete<T>()
{
Console.WriteLine("This is {0} Delete", this.GetType().Name);
}
public void Update<T>()
{
Console.WriteLine("This is {0} Update", this.GetType().Name);
}
public void Query<T>()
{
Console.WriteLine("This is {0} Query", this.GetType().Name);
}
}
public class OracleHelper : IHelper
{
public void Add<T>()
{
Console.WriteLine("This is {0} Add", this.GetType().Name);
}
public void Delete<T>()
{
Console.WriteLine("This is {0} Delete", this.GetType().Name);
}
public void Update<T>()
{
Console.WriteLine("This is {0} Update", this.GetType().Name);
}
public void Query<T>()
{
Console.WriteLine("This is {0} Query", this.GetType().Name);
}
}
public class SqlserverHelper : IHelper
{
public void Add<T>()
{
Console.WriteLine("This is {0} Add", this.GetType().Name);
}
public void Delete<T>()
{
Console.WriteLine("This is {0} Delete", this.GetType().Name);
}
public void Update<T>()
{
Console.WriteLine("This is {0} Update", this.GetType().Name);
}
public void Query<T>()
{
Console.WriteLine("This is {0} Query", this.GetType().Name);
}
}
上面的代码mysql Oracle SQLserver都实现了IHelper接口这里如果想要对接Redis就需要使用适配器
/// <summary>
/// 第三方提供的 openstack servicestack
/// 不能修改
/// </summary>
public class RedisHelper
{
public void AddRedis<T>()
{
Console.WriteLine("This is {0} Add", this.GetType().Name);
}
public void DeleteRedis<T>()
{
Console.WriteLine("This is {0} Delete", this.GetType().Name);
}
public void UpdateRedis<T>()
{
Console.WriteLine("This is {0} Update", this.GetType().Name);
}
public void QueryRedis<T>()
{
Console.WriteLine("This is {0} Query", this.GetType().Name);
}
}
/// <summary>
/// 通过继承 类适配器模式
/// </summary>
public class RedisHelperClass : RedisHelper, IHelper
{
public void Add<T>()
{
base.AddRedis<T>();
} public void Delete<T>()
{
base.DeleteRedis<T>();
} public void Update<T>()
{
base.UpdateRedis<T>();
} public void Query<T>()
{
base.QueryRedis<T>();
}
}
另外还可以使用适配器执行方法前后做一些拓展
public class CacheHelper
{
public void AddCache<T>()
{
Console.WriteLine("This is {0} Add", this.GetType().Name);
}
public void DeleteCache<T>()
{
Console.WriteLine("This is {0} Delete", this.GetType().Name);
}
public void UpdateCache<T>()
{
Console.WriteLine("This is {0} Update", this.GetType().Name);
}
public void QueryCache<T>()
{
Console.WriteLine("This is {0} Query", this.GetType().Name);
}
}
/// <summary>
/// 通过组合 对象适配器模式
///
/// 组合优于继承
/// </summary>
public class RedisHelperObject : IHelper
{
//private RedisHelper _RedisHelper = new RedisHelper();
private RedisHelper _RedisHelper = null; private CacheHelper _CacheHelper = new CacheHelper();
public RedisHelperObject(RedisHelper redisHelper)//可能是一个抽象接口,注入进来
{
this._RedisHelper = redisHelper;
} public RedisHelperObject()
{
this._RedisHelper = new RedisHelper();
} public void Add<T>()
{
this._CacheHelper.AddCache<T>();
this._RedisHelper.AddRedis<T>();
} public void Delete<T>()
{
this._RedisHelper.DeleteRedis<T>();
} public void Update<T>()
{
this._RedisHelper.UpdateRedis<T>();
} public void Query<T>()
{
this._RedisHelper.QueryRedis<T>();
}
}
前端调用
Console.WriteLine("*****************************");
{
IHelper helper = new SqlserverHelper();
helper.Add<Program>();
helper.Delete<Program>();
helper.Update<Program>();
helper.Query<Program>();
}
Console.WriteLine("*****************************");
{
IHelper helper = new MysqlHelper();
helper.Add<Program>();
helper.Delete<Program>();
helper.Update<Program>();
helper.Query<Program>();
}
Console.WriteLine("*****************************");
{
IHelper helper = new OracleHelper();
helper.Add<Program>();
helper.Delete<Program>();
helper.Update<Program>();
helper.Query<Program>();
}
Console.WriteLine("*****************************");
{
IHelper helper = new RedisHelperClass(); //new RedisHelper();
helper.Add<Program>();
helper.Delete<Program>();
helper.Update<Program>();
helper.Query<Program>();
}
{
//侵入性特别强
RedisHelperClass helper = new RedisHelperClass();
helper.Add<Program>();
//helper
}
Console.WriteLine("*****************************");
{
IHelper helper = new RedisHelperObject(); //new RedisHelper();
helper.Add<Program>();
helper.Delete<Program>();
helper.Update<Program>();
helper.Query<Program>();
}
Adapter模式的几个要点:
Adapter模式主要应用于“希望复用一些现存的类,但是接口又与复用环境要求不一致的情况”,在遗留代码复用、类库迁移等方面非常有用。
GOF23定义了两种Adapter模式的实现结构:对象适配器和类适配器。但类适配器采用“多继承”的实现方式,带来不良的高耦合,所以一般不推荐使用。对象适配器采用“对象组合”的方式,更符合松耦合精神。
Adapter模式可以实现的非常灵活,不必拘泥于GOF23中定义的两种结构。例如,完全可以将Adapter模式中的“现存对象“作为新的接口方法参数,来达到适配的目的。
Adapter模式本身要求我们尽可能地使用”面向接口的编程"风格,这样才能在后期很方便的适配。
.NET框架中的Adapter应用:
(1)在.Net中复用com对象:
Com 对象不符合.net对象的接口
使用tlbimp.exe来创建一个Runtime Callable Wrapper(RCW)以使其符合.net对象的接口。
(2).NET数据访问类(Adapter变体):
各种数据库并没有提供DataSet接口
使用DBDataAdapter可以将任何各数据库访问/存取适配到一个DataSet对象上。
(3)集合类中对现有对象的排序(Adapter变体);
现有对象未实现IComparable接口
实现一个排序适配器(继承IComparer接口),然后在其Compare方法中对两个对象进行比较。
本文参考文档:https://www.cnblogs.com/abcdwxc/archive/2007/09/04/881674.html
https://www.cnblogs.com/liqingwen/p/6560899.html
23种设计模式之适配器模式(Adapter Pattern)的更多相关文章
- 二十四种设计模式:适配器模式(Adapter Pattern)
适配器模式(Adapter Pattern) 介绍将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作.示例有一个Message实体类 ...
- 怎样让孩子爱上设计模式 —— 7.适配器模式(Adapter Pattern)
怎样让孩子爱上设计模式 -- 7.适配器模式(Adapter Pattern) 标签: 设计模式初涉 概念相关 定义: 适配器模式把一个类的接口变换成client所期待的还有一种接口,从而 使原本因接 ...
- 乐在其中设计模式(C#) - 适配器模式(Adapter Pattern)
原文:乐在其中设计模式(C#) - 适配器模式(Adapter Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 适配器模式(Adapter Pattern) 作者:webabc ...
- 【设计模式】适配器模式 Adapter Pattern
适配器模式在软件开发界使用及其广泛,在工业界,现实中也是屡见不鲜.比如手机充电器,笔记本充电器,广播接收器,电视接收器等等.都是适配器. 适配器主要作用是让本来不兼容的两个事物兼容和谐的一起工作.比如 ...
- Java设计模式之适配器模式(Adapter Pattern)
Adapter Pattern的作用是在不改变功能的前提下转换接口.Adapter分为两类,一类是Object Adapter, 还有一类是Class Adapter.因为Class Adapter的 ...
- 【Unity与23种设计模式】适配器模式(Adapter)
GoF中定义: "将一个类的接口转换成为客户端期待的类接口.适配器模式让原本接口不兼容的类能一起合作." 适配器模式与装饰模式有一定的相似之处 两者都是在着手解决C#不能多继承的问 ...
- 23种设计模式之适配器模式(Adapter)
适配器模式将一个接口转换成客户希望的另一个接口,从而使接口不兼容的那些类可以一起工作.适配器模式既可以作为类结构型模式,也可以作为对象结构型模式.在类适配器模式中,通过使用一个具体类将适配者适配到目标 ...
- 夜话JAVA设计模式之适配器模式(adapter pattern)
适配器模式:将一个类的接口,转换成客户期望的另一个接口,让不兼容的接口变成兼容. 1.类适配器模式:通过多重继承来实现适配器功能.多重继承就是先继承要转换的实现类,再实现被转换的接口. 2.对象适配器 ...
- 【UE4 设计模式】适配器模式 Adapter Pattern
概述 描述 将一个接口转换成客户希望的另一个接口,适配器模式使接口不兼容的那些类可以一起工作,其别名为包装器(Wrapper). 套路 Target(目标抽象类) 目标抽象类定义了客户所需要的接口,可 ...
随机推荐
- Liunx软件安装之Zabbix监控软件
Zabbix 是什么 zabbix(音同 za:bix)是一个基于 WEB 界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案. zabbix 能监视各种网络参数,保证服务器系统的安全运营 ...
- Mysql系列 - 第3天:管理员必备技能(必须掌握)
这是mysql系列第3篇文章. 环境:mysql5.7.25,cmd命令中进行演示. 在玩mysql的过程中,经常遇到有很多朋友在云上面玩mysql的时候,说我创建了一个用户为什么不能登录?为什么没有 ...
- 【管理学】PDCA
- POJ-2387 Til the Cows Come Home ( 最短路 )
题目链接: http://poj.org/problem?id=2387 Description Bessie is out in the field and wants to get back to ...
- 【Offer】[34] 【二叉树中和为某一值的路径】
题目描述 思路分析 测试用例 Java代码 代码链接 题目描述 输入一棵二叉树和一个整数,打印出二叉树中节点值的和为输入整数的所有路径.从树的根节点开始往下一直到叶节点所经过的节点形成一条路径.  ...
- 分库分表之后,id 主键如何处理?
其实这是分库分表之后你必然要面对的一个问题,就是 id 咋生成?因为要是分成多个表之后,每个表都是从 1 开始累加,那肯定不对啊,需要一个全局唯一的 id 来支持.所以这都是你实际生产环境中必须考虑的 ...
- vsnprint参数和意义
_vsnprintf(char *str, size_t size, const char *format, va_list ap) char *str [out],把生成的格式化的字符串存放在这里. ...
- 致初学者(一): HDU 2000~ 2013题解
对于开始学习C语言程序设计或C++程序设计面向过程部分的同学来说,利用在线OJ网站进行实践训练,对提高自己的编程能力很有好处.国内外OJ网站很多,每个都去看看,去刷个题,是不现实的,也没必要.即使一个 ...
- springmvc 事务控制与数据库隔离级别
springmvc 事物传播与数据库隔离控制 http://www.cnblogs.com/yangy608/archive/2011/06/29/2093478.html 一.Propagation ...
- Android 点九图机制讲解及在聊天气泡中的应用
点九图简介 Android为了使用同一张图作为不同数量文字的背景,设计了一种可以指定区域拉伸的图片格式".9.png",这种图片格式就是点九图. 注意:这种图片格式只能被使用于An ...