设计模式笔记:适配器模式(Adapter)
1. 适配器模式简介
1.1 模式定义
适配器模式:通过一个类的接口转换成客户希望的另外一个接口,使原本由于接口不兼容而不能一起工作的那些类可以一起工作。
适配器从结构上分为:类适配器和对象适配器。其中类适配器使用继承关系来对类进行适配,对象适配器使用对象引用来进行适配。
C#实现类适配器时,Target只能是接口。实现对象适配器时,Target可以是抽象类也可以是接口。
1.2 使用频率
中高
2. 类适配器模式结构
2.1 结构图
2.1.1 类适配器结构图

2.1.2 对象适配器结构图

2.2 参与者
适配器模式参与者:
◊ Target:Client所使用的目标接口,可以是接口或抽象类。由于C#不支持多类继承,故把Target定义为接口。
◊ Adaptee:需要适配的类接口。
◊ Adapter:适配器,负责Adaptee的接口与Target接口进行适配。
◊ Client:与符合Target接口的对象协调的类。
在适配器模式中,类Adapter实现适配器的功能,它在Client与Adaptee之间加入Adapter,这样Client把请求发给接口为Target的类Adapter,再由Adapter调用Adaptee,从而实现Client调用Adaptee。
3. 适配器模式结构实现
3.1 类适配器结构实现

ITarget.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DesignPatterns.AdapterPattern.Structural.ClassAdapter
{
public interface ITarget
{
void Request();
}
}
Adaptee.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DesignPatterns.AdapterPattern.Structural.ClassAdapter
{
public class Adaptee
{
public void SpecificRequest()
{
Console.WriteLine("Called SpecificRequest()");
}
}
}
Adapter.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DesignPatterns.AdapterPattern.Structural.ClassAdapter
{
public class Adapter : Adaptee, ITarget
{
public void Request()
{
this.SpecificRequest();
}
}
}
Client.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DesignPatterns.AdapterPattern.Structural.ClassAdapter
{
public class Client
{
static void Main(string[] args)
{
ITarget t = new Adapter();
t.Request();
}
}
}
运行输出:
Called SpecificRequest()
请按任意键继续. . .
3.2 对象适配器结构实现
Client需要调用Request方法,而Adaptee并没有该方法,为了使Client能够使用Adaptee类,需要提供一个类Adapter。这个类包含了一个Adaptee的实例,将Client与Adaptee衔接起来。
ITarget.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DesignPatterns.AdapterPattern.Structural.ObjectAdapter
{
public interface ITarget
{
void Request();
}
}
Target.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DesignPatterns.AdapterPattern.Structural.ObjectAdapter
{
public class Target : ITarget
{
public virtual void Request()
{
Console.WriteLine("Called Target Request()");
}
}
}
Adaptee.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DesignPatterns.AdapterPattern.Structural.ObjectAdapter
{
public class Adaptee
{
public void SpecificRequest()
{
Console.WriteLine("Called SpecificRequest()");
}
}
}
Adapter.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DesignPatterns.AdapterPattern.Structural.ObjectAdapter
{
public class Adapter : Target
{
private Adaptee _adaptee = new Adaptee(); public override void Request()
{
_adaptee.SpecificRequest();
}
}
}
Client.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DesignPatterns.AdapterPattern.Structural.ObjectAdapter
{
public class Client
{
static void Main(string[] args)
{
ITarget t = new Adapter();
t.Request();
}
}
}
4. 适配器模式实践应用
以手机充电的电源适配器为例,用适配器模式的解决方案。

4.1 类适配器结构实现
ITarget.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DesignPatterns.AdapterPattern.Practical.ClassAdapter
{
public interface ITarget
{
void GetPower();
}
}
Power.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DesignPatterns.AdapterPattern.Practical.ClassAdapter
{
public class Power
{
public void GetPower220V()
{
Console.WriteLine("从电源中得到220V的电压");
}
}
}
Adapter.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DesignPatterns.AdapterPattern.Practical.ClassAdapter
{
public class Adapter : Power, ITarget
{
public void GetPower()
{
this.GetPower220V();
Console.WriteLine("得到手机的充电电压!");
}
}
}
Client.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DesignPatterns.AdapterPattern.Practical.ClassAdapter
{
public class Client
{
static void Main(string[] args)
{
Console.WriteLine("手机:");
ITarget t = new Adapter();
t.GetPower();
}
}
}
运行输出:
手机:
从电源中得到220V的电压
得到手机的充电电压!
请按任意键继续. . .
4.2>、对象适配器结构实现
ITarget.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DesignPatterns.AdapterPattern.Practical.ObjectAdapter
{
public interface ITarget
{
void GetPower();
}
}
Power.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DesignPatterns.AdapterPattern.Practical.ObjectAdapter
{
public class Power
{
public void GetPower220V()
{
Console.WriteLine("从电源中得到220V的电压");
}
}
}
Adapter.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DesignPatterns.AdapterPattern.Practical.ObjectAdapter
{
public class Adapter : ITarget
{
public Power _power;
public Adapter(Power power)
{
this._power = power;
} /// <summary>
/// 得到想要的电压
/// </summary>
public void GetPower()
{
_power.GetPower220V();
Console.WriteLine("得到手机的充电电压!");
}
}
}
Client.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace DesignPatterns.AdapterPattern.Practical.ObjectAdapter
{
public class Client
{
static void Main(string[] args)
{
Console.WriteLine("手机:");
ITarget t = new Adapter(new Power());
t.GetPower();
}
}
}
5、适配器模式应用分析
适配器模式适用情形:
◊ 当适用一个已存在的类,而它的接口不符合所要求的情况;
◊ 想要创建一个可以复用的类,该类可以与原接口的类协调工作;
◊ 在对象适配中,当要匹配数个子类的时候,对象适配器可以适配它们的父类接口。
适配器模式特点:
类适配器
◊ 使得Adapter可以重定义Adaptee的部分行为。因为Adapter是Adaptee的一个子类;
◊ 仅仅引入了一个对象,并不需要额外的指针间接得到Adaptee。
对象适配器
◊ 允许一个Adapter与多个Adaptee同时工作。Adapter也可以一次给所有的Adaptee添加功能;
◊ 使得重定义Adaptee的行为比较困难。需要生成一个Adaptee的子类,然后使Adapter引入这个子类而不是引用Adaptee本身。
设计模式笔记:适配器模式(Adapter)的更多相关文章
- 设计模式 笔记 适配器模式 Adapter
//---------------------------15/04/13---------------------------- //Adapter 适配器模式 ----类对象结构型模式 /* 1: ...
- 乐在其中设计模式(C#) - 适配器模式(Adapter Pattern)
原文:乐在其中设计模式(C#) - 适配器模式(Adapter Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 适配器模式(Adapter Pattern) 作者:webabc ...
- 8.3 GOF设计模式二: 适配器模式 Adapter
GOF设计模式二: 适配器模式 Adapter 为中国市场生产的电器,到了美国,需要有一个转接器才能使用墙上的插座,这个转接 器的功能.原理?复习单实例模式 SingleTon的三个关键点 ...
- 怎样让孩子爱上设计模式 —— 7.适配器模式(Adapter Pattern)
怎样让孩子爱上设计模式 -- 7.适配器模式(Adapter Pattern) 标签: 设计模式初涉 概念相关 定义: 适配器模式把一个类的接口变换成client所期待的还有一种接口,从而 使原本因接 ...
- 二十四种设计模式:适配器模式(Adapter Pattern)
适配器模式(Adapter Pattern) 介绍将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作.示例有一个Message实体类 ...
- 【设计模式】适配器模式 Adapter Pattern
适配器模式在软件开发界使用及其广泛,在工业界,现实中也是屡见不鲜.比如手机充电器,笔记本充电器,广播接收器,电视接收器等等.都是适配器. 适配器主要作用是让本来不兼容的两个事物兼容和谐的一起工作.比如 ...
- Java设计模式之适配器模式(Adapter)
转载:<JAVA与模式>之适配器模式 这个总结的挺好的,为了加深印象,我自己再尝试总结一下 1.定义: 适配器模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法 ...
- JavaScript设计模式 Item9 --适配器模式Adapter
适配器模式(转换器面模式),通常是为要使用的接口,不符本应用或本系统使用,而需引入的中间适配层类或对象的情况. 适配器模式的作用是解决两个软件实体间的接口不兼容的问题. 一.定义 适配器模式(Adap ...
- python 设计模式之适配器模式 Adapter Class/Object Pattern
#写在前面 看完了<妙味>和<华医>,又情不自禁的找小说看,点开了推荐里面随机弹出的<暗恋.橘生淮南>,翻了下里面的评论,有个读者从里面摘了一段自己很喜欢的话出来, ...
- [设计模式] 7 适配器模式 adapter
在 Adapter 模式的结构图中可以看到,类模式的 Adapter 采用继承的方式复用 Adaptee的接口,而在对象模式的 Adapter 中我们则采用组合的方式实现 Adaptee 的复用 类模 ...
随机推荐
- MATLAB——神经网络构造线性层函数linearlayer
% example5_7.m x=-:; y=*x-; randn(); % 设置种子,便于重复执行 y=y+randn(,length(y))*1.5; % 加入噪声的直线 plot(x,y,'o' ...
- 【Codeforces 1105E】Helping Hiasat
Codeforces 1105 E 题意:给你m个事件,每个事件可能是以下两种之一: \(1\),代表此时可以更改用户名 \(2\) \(s\),代表\(s\)来查看是否用户名与其名字相符 一共有\( ...
- JAVA体系的线程的实现,线程的调度,状态的转换
java体系中线程的实现 1.使用内核线程实现 内核线程就是直接由操作系统内核支持的线程,这种线程由内核来完成线程切换,内核通过操作调度器对线程进行调度,并负责将线程的任务映射到各个处理器上,每个内核 ...
- Luogu3199 HNOI2009 最小圈 分数规划、SPFA
传送门 可以发现它的式子是一个分数规划的式子,所以可以二分答案,将所有边权减掉当前二分值之后跑一边$SPFA$判断负环即可. 然而这道题把$BFS-SPFA$卡掉了却没卡$DFS-SPFA$ 出题人: ...
- Luogu4768 NOI2018 归程 最短路、Kruskal重构树
传送门 题意:给出一个$N$个点.$M$条边的图,每条边有长度和海拔,$Q$组询问,每一次询问从$v$开始,经过海拔超过$p$的边所能到达的所有点中到点$1$的最短路的最小值,强制在线.$N \leq ...
- QZEZ第一届“饭吉圆”杯程序设计竞赛
终于到了饭吉圆杯的开赛,这是EZ我参与的历史上第一场ACM赛制的题目然而没有罚时 不过题目很好,举办地也很成功,为法老点赞!!! 这次和翰爷,吴骏达 dalao,陈乐扬dalao组的队,因为我们有二个 ...
- [Oracle]数据库的Control File 取Dump后的样例
[Oracle]数据库的Control File 取Dump后的样例: 片段截取-------------------------------(size = 40, compat size = 40, ...
- Pycharm: 代码跳转如何回退 (小技巧)
背景 玩Python已经有段时间了, 一般都是通过vim和Pycharm来开发, 真心觉得这两个是神器. Vim神器暂且不说, 今天来分享Pycharm的一个小技巧. 用Pycharm的童鞋都知道, ...
- Redis哨兵模式(sentinel)学习总结及部署记录(主从复制、读写分离、主从切换)
Redis的集群方案大致有三种:1)redis cluster集群方案:2)master/slave主从方案:3)哨兵模式来进行主从替换以及故障恢复. 一.sentinel哨兵模式介绍Sentinel ...
- centos7下/etc/rc.local文件里配置的开机启动项不执行的解决办法
习惯于在/etc/rc.local文件里配置我们需要开机启动的服务,这个在centos6系统下是正常生效的.但是到了centos7系统下,发现/etc/rc.local文件里的开机启动项不执行了!仔细 ...