结构型模式——适配器模式

来源:互联网 发布:窗帘算法 编辑:程序博客网 时间:2024/04/28 21:11

1.由来

客户端可以通过目标类的接口访问它所提供的服务。有时,现有的类可以满足客户类的功能需要,但是它所提供的接口不一定是客户类所期望的,现有的接口需要转化为客户类期望的接口,这样保证了对现有类的重用。

看图吧,能跟好的理解:

      

      


2.定义

适配器模式(Adapter Pattern) :将一个接口转换成客户希望的另一个接口,适配器模式使接口不兼容的那些类可以一起工作,其别名为包装器(Wrapper)。适配器模式既可以作为类结构型模式,也可以作为对象结构型模式。


3.代码的实现

这里又分为两种实现方式:

     (1)类的适配器模式(采用继承实现)

[html] view plain copy
  1. // 已存在的、具有特殊功能、但不符合我们既有的标准接口的类    
  2. class Adaptee {    
  3.     public void specificRequest() {    
  4.         System.out.println("被适配类具有 特殊功能...");    
  5.     }    
  6. }    
  7.     
  8. // 目标接口,或称为标准接口    
  9. interface Target {    
  10.     public void request();    
  11. }    
  12.     
  13. // 具体目标类,只提供普通功能    
  14. class ConcreteTarget implements Target {    
  15.     public void request() {    
  16.         System.out.println("普通类 具有 普通功能...");    
  17.     }    
  18. }    
  19.      
  20. // 适配器类,继承了被适配类,同时实现标准接口    
  21. class Adapter extends Adaptee implements Target{    
  22.     public void request() {    
  23.         super.specificRequest();    
  24.     }    
  25. }    
  26.      
  27. // 测试类public class Client {    
  28.     public static void main(String[] args) {    
  29.         // 使用普通功能类    
  30.         Target concreteTarget = new ConcreteTarget();    
  31.         concreteTarget.request();    
  32.             
  33.         // 使用特殊功能类,即适配类    
  34.         Target adapter = new Adapter();    
  35.         adapter.request();    
  36.     }    
  37. }    


     (2)对象适配器(采用对象组合方式实现)

[html] view plain copy
  1. // 适配器类,直接关联被适配类,同时实现标准接口    
  2. class Adapter implements Target{    
  3.     // 直接关联被适配类    
  4.     private Adaptee adaptee;    
  5.         
  6.     // 可以通过构造函数传入具体需要适配的被适配类对象    
  7.     public Adapter (Adaptee adaptee) {    
  8.         this.adaptee = adaptee;    
  9.     }    
  10.         
  11.     public void request() {    
  12.         // 这里是使用委托的方式完成特殊功能    
  13.         this.adaptee.specificRequest();    
  14.     }    
  15. }    
  16.     
  17. // 测试类    
  18. public class Client {    
  19.     public static void main(String[] args) {    
  20.         // 使用普通功能类    
  21.         Target concreteTarget = new ConcreteTarget();    
  22.         concreteTarget.request();    
  23.             
  24.         // 使用特殊功能类,即适配类,    
  25.         // 需要先创建一个被适配类的对象作为参数    
  26.         Target adapter = new Adapter(new Adaptee());    
  27.         adapter.request();    
  28.     }    
  29. }    

个人感觉两种方式 还是差不多。

4.模式的优点

  • 将目标类和适配者类解耦,通过引入一个适配器类来重用现有的适配者类,而无须修改原有代码。
  • 增加了类的透明性和复用性,将具体的实现封装在适配者类中,对于客户端类来说是透明的,而且提高了适配者的复用性。
  • 灵活性和扩展性都非常好,通过使用配置文件,可以很方便地更换适配器,也可以在不修改原有代码的基础上增加新的适配器类,完全符合“开闭原则”。
类适配器模式还具有如下优点:
由于适配器类是适配者类的子类,因此可以在适配器类中置换一些适配者的方法,使得适配器的灵活性更强。
对象适配器模式还具有如下优点:
一个对象适配器可以把多个不同的适配者适配到同一个目标,也就是说,同一个适配器可以把适配者类和它的子类都适配到目标接口。

5.模式的缺点


类适配器模式的缺点如下:
对于Java、C#等不支持多重继承的语言,一次最多只能适配一个适配者类,而且目标抽象类只能为抽象类,不能为具体类,其使用有一定的局限性,不能将一个适配者类和它的子类都适配到目标接口。
对象适配器模式的缺点如下:
与类适配器模式相比,要想置换适配者类的方法就不容易。如果一定要置换掉适配者类的一个或多个方法,就只好先做一个适配者类的子类,将适配者类的方法置换掉,然后再把适配者类的子类当做真正的适配者进行适配,实现过程较为复杂。

6.应用场景

  • 系统需要使用现有的类,而这些类的接口不符合系统的需要。
  • 想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作


参考:http://design-patterns.readthedocs.io/zh_CN/latest/structural_patterns/adapter.html
http://blog.csdn.net/jason0539/article/details/22468457    
0 0
原创粉丝点击