设计模式---适配器模式

闲聊 闲聊 1367 人阅读 | 0 人回复

<
适配器形式




引见

适配器形式(Adapter Pattern):将一个接心转换成客户盼望的另外一个接心,使接心没有兼容的那些类能够一同事情,其别号为包拆器(Wrapper)。适配器形式既能够做为类规划型形式,也能够做为工具规划型形式。
正在适配器形式中,我们经由过程增长一个新的适配器类去处理接心没有兼容的成绩,使得本来出有任何干系的类能够协同事情。
按照适配器类取适配者类的干系不同,适配器形式可分为工具适配器战类适配器两种,正在工具适配器形式中,适配器取适配者之间是联系关系(散开)干系;正在类适配器形式中,适配器取适配者之间是担当(或完成)干系。

事情道理



  • 适配器形式:将一个类的接心转换成另外一种接心,让本来接心没有兼容的类能够兼容;
  • 从用户的角度看没有到被适配者;
  • 用户挪用适配器转化出去的目的接心办法,适配器再挪用被适配者的相干接心办法;

类适配器形式演示

以保存中充电器为例,充电器自己相称于适配者 (Adapter),220V 交流电相称于被适配者,我们的目的(target) 念把220V交流电转成5V曲流电
要适配的类,即需求将220v电压转化为5v电压
  1. //中国的电压220V
  2. public class ChinaPower
  3. {
  4.     private final Integer outPut=220;
  5.     public Integer getOutPut() {
  6.         return outPut;
  7.     }
  8. }
复造代码
适配器接心,只卖力界说转化需求利用的营业逻辑办法,详细完成交由适配器类完成
  1. //将电压转化为5v---适配接心
  2. public interface TransTo5V
  3. {
  4.     Integer transTo5V();
  5. }
复造代码
适配器类,担当了ChinaPower,并完成了适配器接心,卖力完成讲220v电压转化为5v的详细营业逻辑代码完成
  1. //适配器类---完成适配器接心
  2. public class ChinaAdapter extends ChinaPower implements TransTo5V
  3. {
  4.     //将220v电压转换为5v的
  5.     @Override
  6.     public Integer transTo5V()
  7.     {
  8.         //得到被适配类,即我们需求将220v电压转化为5v返回
  9.         Integer output=super.getOutPut();
  10.         //停止电压转换操纵
  11.         return output/44;
  12.     }
  13. }
复造代码
Phone类,需求用到适配器举办兼容,如许才能够充电
  1. //脚机需求5v的电压停止充电
  2. public class Phone
  3. {
  4.     //经由过程适配器得到5v的电压
  5.     public void charging(ChinaAdapter chinaAdapter)
  6.     {
  7.         if(5==chinaAdapter.transTo5V())
  8.         {
  9.             System.out.println("获得5v,充电中...");
  10.         }
  11.         else
  12.         {
  13.             System.out.println("电压太高,脚机压力过年夜");
  14.         }
  15.     }
  16. }
复造代码
充电测试
  1. public class test
  2. {
  3.     @Test
  4.     public void test()
  5.     {
  6.         Phone p=new Phone();
  7.         p.charging(new ChinaAdapter());
  8.     }
  9. }
复造代码
144731ufoqmpamj8fam5d6.png


接心适配器形式



  • 接心适配器形式(Default Adapter Pattern),也叫缺省适配器形式;
  • 中心思路:当没有需求局部完成接心供给的办法时,可先设想一个笼统类完成接心,并为该接心中每一个办法供给一个默许完成(空办法),该笼统类的子类可有挑选天笼盖女类的某些办法去完成需供;
  • 合用于一个接心没有念利用其一切的办法的状况;
界说一个适配器接心:
  1. //适配器类---完成适配器接心
  2. public class ChinaAdapter implements TransTo5V
  3. {
  4.     private ChinaPower chinaPower;
  5.     //经由过程机关器,完成赋值
  6.     public ChinaAdapter(ChinaPower chinaPower)
  7.     {
  8.      this.chinaPower=chinaPower;   
  9.     }
  10.     //将220v电压转换为5v的
  11.     @Override
  12.     public Integer transTo5V()
  13.     {
  14.         //得到被适配类,即我们需求将220v电压转化为5v返回
  15.         Integer output=chinaPower.getOutPut();
  16.         //停止电压转换操纵
  17.         return output/44;
  18.     }
  19. }
复造代码
笼统类 AbsAdapter 将 InterfaceTest 的办法举办默许完成,当子类需求利用适配器接心中的某个办法,而没有是局部办法时,就能够经由过程担当笼统类,去完成对需求利用的特定办法重写操纵便可,无需完成适配器接心内里的局部办法
  1. public class test
  2. {
  3.     @Test
  4.     public void test()
  5.     {
  6.         Phone p=new Phone();
  7.         p.charging(new ChinaAdapter(new ChinaPower()));
  8.     }
  9. }
复造代码
Client 挪用接心,重写适配器笼统类办法
  1. public interface InterfaceTest {
  2.         public void m1();
  3.         public void m2();
  4.         public void m3();
  5.         public void m4();
  6. }
复造代码

适配器形式总结

次要长处



  • 将目的类战适配者类解耦,经由过程引进一个适配器类去重用现有的适配者类,不必修正本有规划。
  • 增长了类的通明性战复用性,将详细的营业完成历程启拆正在适配者类中,关于客户端类而行是通明的,并且进步了适配者的复用性,统一个适配者类能够正在多个不同的体系中复用。
  • 灵活性战扩大性皆十分好,经由过程利用设置文件,能够很便利天改换适配器,也能够正在没有修正本有代码的根底上增长新的适配器类,完整契合“开闭准绳”。
详细来讲,类适配器形式另有以下长处:


  • 因为适配器类是适配者类(适配器接心或适配器接话柄现的笼统类)的子类,因而能够正在适配器类中置换一些适配者(适配器接心或适配器接话柄现的笼统类)的办法,使得适配器的灵活性更强。
  • 一个工具适配器能够把多个不同的适配者(适配器接心或适配器接话柄现的笼统类)适配到统一个目的;
  • 能够适配一个适配者的子类,因为适配器战适配者(适配器接心或适配器接话柄现的笼统类)之间是联系关系干系,按照“里氏代换准绳”,适配者(适配器接心或适配器接话柄现的笼统类)的子类也可经由过程该适配器举办适配。

合用场景



  • 体系需求利用一些现有的类,而那些类的接心(如办法名)没有契合体系的需求,以至出有那些类的源代码。
  • 念创立一个能够反复利用的类,用于取一些相互之间出有太年夜联系关系的一些类,包罗一些大要正在未来引进的类一同事情。

恳求处理办法中适配器形式部门源码探求

144731gufsiyh9rbiyvibv.jpg

Spring MVC中的适配器形式次要用于施行目的 Controller 中的恳求处理办法。
正在Spring MVC中,DispatcherServlet 做为用户,HandlerAdapter 做为盼望接心(适配器接心),详细的适配器完成类用于对目的类举办适配,Controller 做为需求适配的类。
为何要正在 Spring MVC 中利用适配器形式?Spring MVC 中的 Controller 品种浩瀚,不同范例的 Controller 经由过程不同的办法去对恳求举办处理。假如倒霉用适配器形式的话,DispatcherServlet 间接获得对应范例的 Controller,需求的自止去断定,像上面那段代码一样:
  1. public abstract class AbsAdapter implements InterfaceTest {
  2.         //默许完成
  3.         public void m1() {}
  4.         public void m2() {}
  5.         public void m3() {}
  6.         public void m4() {}
  7. }
复造代码
如许假定假如我们增长一个 HardController,便要正在代码中参加一止 if(mappedHandler.getHandler() instanceof HardController),这类情势便使得程序易以保护,也违背了设想形式中的开闭准绳 – 对扩大开放,对修正封闭。
我们去看看源码,起首是适配器接心 HandlerAdapter
  1. public class Client {
  2.         public static void main(String[] args) {
  3.                
  4.                 AbsAdapter absAdapter = new AbsAdapter() {
  5.                         //只需求来笼盖我们 需求利用 接心办法
  6.                         @Override
  7.                         public void m1() {
  8.                                 System.out.println("利用了m1的办法");
  9.                         }
  10.                 };
  11.                
  12.                 absAdapter.m1();
  13.         }
  14. }
复造代码
现该接心的适配器每个 Controller 皆有一个适配器取之对应,如许的话,每自界说一个 Controller 需求界说一个完成 HandlerAdapter 的适配器。
springmvc 中供给的 Controller 完成类有以下:
144731svccgvkoc36kh6qk.jpg

springmvc 中供给的 HandlerAdapter 完成类以下
144731fbwdx81otwt1jjxb.jpg

HttpRequestHandlerAdapter 那个适配器代码以下:
  1. public interface Power
  2. {
  3.      Integer getOutPut();
  4. }
复造代码
当Spring容器启动后,会将一切界说好的适配器工具寄存正在一个List汇合中,当一个恳求去临时,DispatcherServlet 会经由过程 handler 的范例找到对应适配器,并将该适配器工具返回给用户,然后就能够统一经由过程适配器的 hanle() 办法去挪用 Controller 中的用于处理恳求的办法。
  1. //中国的电压220V
  2. public class ChinaPower implements Power
  3. {
  4.     private final Integer outPut=220;
  5.     @Override
  6.     public Integer getOutPut() {
  7.         return outPut;
  8.     }
  9. }
复造代码
经由过程适配器形式我们将一切的 controller 统一交给 HandlerAdapter 处理,免除了写大批的 if-else 语句对 Controller 举办断定,也更利于扩大新的 Controller 范例。

参考文章

设想形式 8 - 适配器形式取springmvc源码阐发
设想形式 | 适配器形式及典范使用
适配器形式(SpringMVC源码阐发)
设想形式 | 适配器形式及典范使用

免责声明:假如进犯了您的权益,请联络站少,我们会实时删除侵权内乱容,感谢协作!
1、本网站属于个人的非赢利性网站,转载的文章遵循原作者的版权声明,如果原文没有版权声明,按照目前互联网开放的原则,我们将在不通知作者的情况下,转载文章;如果原文明确注明“禁止转载”,我们一定不会转载。如果我们转载的文章不符合作者的版权声明或者作者不想让我们转载您的文章的话,请您发送邮箱:Cdnjson@163.com提供相关证明,我们将积极配合您!
2、本网站转载文章仅为传播更多信息之目的,凡在本网站出现的信息,均仅供参考。本网站将尽力确保所提供信息的准确性及可靠性,但不保证信息的正确性和完整性,且不对因信息的不正确或遗漏导致的任何损失或损害承担责任。
3、任何透过本网站网页而链接及得到的资讯、产品及服务,本网站概不负责,亦不负任何法律责任。
4、本网站所刊发、转载的文章,其版权均归原作者所有,如其他媒体、网站或个人从本网下载使用,请在转载有关文章时务必尊重该文章的著作权,保留本网注明的“稿件来源”,并自负版权等法律责任。
回复 关闭延时

使用道具 举报

 
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则