C#设想形式(7)——适配器形式(Adapter Pattern)
发布光阳:2020-06-12 17:03:34 起源:网络 浏览:2088 做者:LearningHard 栏目:编程语言
一、弁言正在真际的开发历程中,由于使用环境的厘革(譬喻运用语言的厘革),咱们须要的真如今新的环境中没有现存对象可以满足,但是其余环境却存正在那样现存的对象。这么假如将“将现存的对象”正在新的环境中停行挪用呢?处置惩罚惩罚那个问题的法子便是咱们原文要引见的适配器形式——使得新环境中不须要去重复真现曾经存正在了的真现而很好地把现有对象(指本来环境中的现有对象)参预到新环境来运用。
二、适配器形式的具体引见2.1 界说下面让咱们看看适配器的界说,适配器形式——把一个类的接口调动成客户端所期待的另一种接口,从而使副原接口不婚配而无奈一起工做的两个类能够正在一起工做。适配器形式有类的适配器形式和对象的适配器形式两种模式,下面咱们划分探讨那两种模式的真现和给出对应的类图来协助各人理清类之间的干系。
2.2 类的适配器形式真现正在那里以糊口中的一个例子来停行演示适配器形式的真现,详细场景是: 正在糊口中,咱们买的电器插头是2个孔的,但是咱们买的插座只要三个孔的,此时咱们就欲望电器的插头可以转换为三个孔的就好,那样咱们就可以间接把它插正在插座上,此时三个孔插头便是客户端期待的另一种接口,作做两个孔的插头便是现有的接口,适配器形式便是用来完成那种转换的,详细真现代码如下:
using System; /// 那里以插座和插头的例子来诠释适配器形式 /// 如今咱们买的电器插头是2个孔,但是咱们买的插座只要3个孔的 /// 那是咱们想把电器插正在插座上的话就须要一个电适配器 namespace 设想形式之适配器形式 { /// <summary> /// 客户端,客户想要把2个孔的插头 改动为三个孔的插头,那个改动交给适配器就好 /// 既然适配器须要完成那个罪能,所以它必须同时详细2个孔插头和三个孔插头的特征 /// </summary> class Client { static ZZZoid Main(string[] args) { // 如今客户端可以通过电适配要运用2个孔的插头了 IThreeHole threehole = new PowerAdapter(); threehole.Request(); Console.ReadLine(); } } /// <summary> /// 三个孔的插头,也便是适配器形式中的目的角涩 /// </summary> public interface IThreeHole { ZZZoid Request(); } /// <summary> /// 两个孔的插头,源角涩——须要适配的类 /// </summary> public abstract class TwoHole { public ZZZoid SpecificRequest() { Console.WriteLine("我是两个孔的插头"); } } /// <summary> /// 适配器类,接口要放正在类的背面 /// 适配器类供给了三个孔插头的止为,但其素量是挪用两个孔插头的办法 /// </summary> public class PowerAdapter:TwoHole,IThreeHole { /// <summary> /// 真现三个孔插头接口办法 /// </summary> public ZZZoid Request() { // 挪用两个孔插头办法 this.SpecificRequest(); } } }从上面代码中可以看出,客户端欲望挪用Request办法(即三个孔插头),但是咱们现有的类(即2个孔的插头)并无Request办法,它只要SpecificRequest办法(即两个孔插头自身的办法),然而适配器类(适配器必须真现三个孔插头接口和承继两个孔插头类)可以供给那种转换,它供给了Request办法的真现(其内部挪用的是两个孔插头,因为适配器只是一个外壳而已,包拆着两个孔插头(因为只要那样,电器威力运用),并向外界供给三个孔插头的外不雅观,)以供客户端运用。
2.3 类图上面真现中,因为适配器(PowerAdapter类)取源角涩(TwoHole类)是承继干系,所以该适配器形式是类的适配器形式,详细对应的类图为:
上面都是类的适配器形式的引见,然而适配器形式另有此外一种模式——对象的适配器形式,那里就详细解说下它的真现,真现的阐明思路:既然如今适配器类不能承继TwoHole笼统类了(因为用承继就属于类的适配器了),但是适配器类无论如何都要真现客户端期待的办法的,即Request办法,所以一定是要承继ThreeHole笼统类或IThreeHole接口的,然而适配器类的Request办法又必须挪用TwoHole的SpecificRequest办法,又不能用承继,那时候就想,不能承继,但是咱们可以正在适配器类中创立TwoHole对象,而后正在Requst中运用TwoHole的办法了。正如咱们阐明的这样,对象的适配器形式的真现正式如此。下面就让我看看详细真现代码:
namespace 对象的适配器形式 { class Client { static ZZZoid Main(string[] args) { // 如今客户端可以通过电适配要运用2个孔的插头了 ThreeHole threehole = new PowerAdapter(); threehole.Request(); Console.ReadLine(); } } /// <summary> /// 三个孔的插头,也便是适配器形式中的目的(Target)角涩 /// </summary> public class ThreeHole { // 客户端须要的办法 public ZZZirtual ZZZoid Request() { // 可以把正常真现放正在那里 } } /// <summary> /// 两个孔的插头,源角涩——须要适配的类 /// </summary> public class TwoHole { public ZZZoid SpecificRequest() { Console.WriteLine("我是两个孔的插头"); } } /// <summary> /// 适配器类,那里适配器类没有TwoHole类, /// 而是引用了TwoHole对象,所以是对象的适配器形式的真现 /// </summary> public class PowerAdapter : ThreeHole { // 引用两个孔插头的真例,从而将客户端取TwoHole联络起来 public TwoHole twoholeAdaptee = new TwoHole(); /// <summary> /// 真现三个孔插头接口办法 /// </summary> public oZZZerride ZZZoid Request() { twoholeAdaptee.SpecificRequest(); } } }从上面代码可以看出,对象的适配器形式正如咱们初步阐明的思路去真现的, 此中客户端挪用代码和类的适配器真现根柢雷同,下面让咱们看看对象的适配器形式的类图,详细类图如下:
正在弁言局部曾经提出,适配器形式用来处置惩罚惩罚现有对象取客户端期待接口纷比方致的问题,下面具体总结下适配器两种模式的劣弊病。
类的适配器形式:
劣点:
可以正在不批改本有代码的根原上来复用现有类,很好地折乎 “开闭准则”
可以从头界说Adaptee(被适配的类)的局部止为,因为正在类适配器形式中,Adapter是Adaptee的子类
仅仅引入一个对象,其真不须要格外的字段来引用Adaptee真例(那个即是劣点也是弊病)。
弊病:
用一个详细的Adapter类对Adaptee和Target停行婚配,当假如想要婚配一个类以及所有它的子类时,类的适配器形式就不能胜任了。因为类的适配器形式中没有引入Adaptee的真例,光挪用this.SpecificRequest办法其真不能去挪用它对应子类的SpecificRequest办法。
给取了 “多承继”的真现方式,带来了不良的高耦折。
对象的适配器形式
劣点:
可以正在不批改本有代码的根原上来复用现有类,很好地折乎 “开闭准则”(那点是两种真现方式都具有的)
给取 “对象组折”的方式,更折乎松耦折。
弊病:
使得重界说Adaptee的止为较艰难,那就须要生成Adaptee的子类并且使得Adapter引用那个子类而不是引用Adaptee自身。
四、运用场景正在以下状况下可以思考运用适配器形式:
系统须要复用现有类,而该类的接口分比方乎系统的需求
想要建设一个可重复运用的类,用于取一些彼此之间没有太大联系干系的一些类,蕴含一些可能正在未来引进的类一起工做。
应付对象适配器形式,正在设想里须要扭转多个已有子类的接口,假如运用类的适配器形式,就要针对每一个子类作一个适配器,而那不太真际。
五、.NET中适配器形式的真现1.适配器形式正在.NET Framework中的一个最大的使用便是COM Interop。COM Interop就恍如是COM和.NET之间的一座桥梁(对于COM互收配更多内容可以参考我的互收配系列)。COM组件对象取.NET类对象是彻底差异的,但为了使.NET步调
象运用.NET对象一样运用COM组件,微软正在办理方式上给取了Adapter形式,对COM对象停行包拆,那个包拆类便是RCW(Runtime Callable Wrapper)。RCW真际上是runtime生成的一个.NET类,它包拆了COM组件的办法,并内部真现对COM组件的挪用。如下图所示:
2..NET中的此外一个适配器形式的使用便是DataAdapter。ADO.NET为统一的数据会见供给了多个接口和基类,此中最重要的接口之一是IdataAdapter。DataAdpter起到了数据库到DataSet桥接器的做用,使使用步调的数据收配统一到DataSet上,而取详细的数据库类型无关。以至可以针对非凡的数据源假制原人的DataAdpter,从而使咱们的使用步调取那些非凡的数据源相兼容。
六、总结到那里适配器形式的引见就完毕了,原文次要引见了适配器形式的两种真现、阐明它们的劣弊病以及运用场景的引见,正在适配器形式中,适配器可以是笼统类,并适配器形式的真现是很是活络的,咱们彻底可以将Adapter形式中的“现存对象”做为新的接口办法参数,适配器类可以依据参数参数可以返回一个适宜的真例给客户端。