设计模式系列 - Adapter模式

简介:

 

"将一个类的接口转换成客户希望的另一个接口,Adapter模式使原本由于接口不兼容而不能一起工作的类可以一起工作" 。简单的说,就是利用现有的接口去包装一个第三方的接口使其能象现有接口一样被程序调用,而不考虑实际使用类的差异

 

意图
将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。(GoF)

场景
  相信很多人都知道什么是显卡,也有很多人知道显卡的本名——图形适配器。恩,是的,正好这回说说Apater模式,就拿显卡来例子来分析一下Adapter模式。
  我们知道显示器(Client)是用来显示图形的,它是不能显示数据,它只能够接受来自图形发送设备Target的信号。可是我们手头上只有CPU(Adaptee)这个产生各种描述图形的数据的数据发送器。我们需要将这些数据让显示器进行显示,可是这两个部件却是不兼容的。于是我们需要一个中间设备,它能够将CPU“适配于显示器,这便是我们的显卡——图形适配器(Adapter)

 

 

java 代码

 // 图形发送设备  

  1. public class Target {  

  2.     /** 

  3.      * 传送图形信号 

  4.      */  

  5.     public String request() {  

  6.         return "Graphic sender";  

  7.     }  

 

java 代码 

  1. // 显示器  

  2. public class Client {  

  3.   

  4.     public static void main(String[] args) {  

  5.         Target target = new Targete();  

  6.         System.out.println(target.request());  

  7.     }  

  8. }  


可是我们的CPU(Adaptee)只能输出0/1数据,他是个计算器,而不是图形发送设备(Target)

java 代码 

  1. // CPU  

  2. public class Adaptee {  

  3.     /** 

  4.      * CPU输出的数据 

  5.      */  

  6.     public String getData() {  

  7.         return "CPU data";  

  8.     }  

  9. }  


这个时候我们的显卡(Adapter)的作用便体现出来了,它负责对CPU进行适配,通过将CPU传过来的数据转换成图形信号,从而将CPU伪装成一个图形发送设备。

java 代码 

  1. // 显卡,即我们的适配器  

  2. public class Adapter extends Target {  

  3.   

  4.     // 被代理的设备  

  5.     private Adaptee apt = null;  

  6.   

  7.     /** 

  8.      * 装入被代理的设备 

  9.      */  

  10.     public Adapter(Adaptee apt) {  

  11.         this.apt = apt;  

  12.     }  

  13.   

  14.     /** 

  15.      * 被代理的设备传过来的数据转换成为图形输出 

  16.      */  

  17.     public String request() {  

  18.         return apt.getData();  

  19.     }  

  20. }  


这样,我们的电脑的显示流程就变成CPU-显卡-显示器:

java 代码 

  1. public class Client {  

  2.   

  3.     public static void main(String[] args) {  

  4.         // CPU经过显卡的适配后成了图形发送装置了  

  5.         Target target = new Adapter(new Adaptee());  

  6.         System.out.println(target.request());  

  7.     }  

  8.       

  9. }  

上面的这种依赖于对象组合的Adapter模式叫做对象适配器(Object Adapter)。它的特征是继承/实现某一方的类(Target),如这里的图形发送器,同时内部包含一个被适配的类(Adaptee),如这里的CPU。通过重写其父类的方法来进行适配。

 

 

另一种的Adapter实现
对于Adapter模式,还有另外一种实现方式,这种适配方式叫做类适配器(Class Adapter)。它与Object Adapter的不同之处在于它继承被适配的对象。

java 代码 

  1. public class Adapter extends Targer, Adaptee {  

  2.     ......  

  3. }  


这样的代码在C++中是合法的,但是在Java中规定最多只能继承一个父类,而可以实现多个接口。所以我们需要建立一个IAdaptee的接口,然后将我们的Adapter继承Target同时实现IAdaptee

java 代码 

  1. // IAdaptee接口  

  2. public interface IAdaptee {    

  3.  

  4.     String getData();  

  5. }   

 

java 代码 

  1. // Adaptee 实现IAdaptee 

  2. public class Adaptee implements IAdaptee {  

  3.   ......  

  4. }    

 

java 代码 

  1. public class Adapter extends Target implements IAdaptee {  

  2.   

  3.     private IAdaptee apt = null;  

  4.   

  5.     public Adapter(IAdaptee apt) {  

  6.         this.apt = apt;  

  7.     }  

  8.   

  9.     public String request() {  

  10.         return apt.getData();  

  11.     }  

  12.   

  13.     public String getData() {  

  14.         return apt.getData();  

  15.     }  

  16. }  


对于我们的显示器(Client)方面,Class AdapterObject Adapter一样,所以不需要进行修改。

对于Class Adapter,大家也看见了,在Adapter中因为是实现了IAdaptee接口,因此需要实现getData()的接口。一旦TargetIAdaptee拥有相同的方法时,会出现麻烦的。所以尽量优先使用Object Adapter的模式

C: 工作一年多了,纸上的笔记写了不少,但一直没有机会整理。现在离职了,就用这段时间整理一下自己的笔记,也顺便丰富一下自己的博客吧,要不也真的对不起在这里潜水两年的时间。 

适配器:基于现有类所提供的服务,向客户提供接口,以满足客户的期望

==================================================================

方案1:继承

方案2:组合

方案3:给出空实现,对关心的内容注册监听器,例如awt、swing

 
  1. Frame frame = new Frame("new Frame"); 
  2.       frame.addMouseMotionListener(new MouseMotionAdapter() { 
  3.           @Override 
  4.           public void mouseMoved(MouseEvent e) { 
  5.               System.out.println(e.getX() + ", " + e.getY()); 
  6.           } 
  7.  
  8.       }); 
  9.  
  10.       frame.addWindowListener(new WindowAdapter() { 
  11.  
  12.           @Override 
  13.           public void windowClosing(WindowEvent e) { 
  14.               System.out.println("windowClosing"); 
  15.               System.exit(0); 
  16.           } 
  17.  
  18.           @Override 
  19.           public void windowClosed(WindowEvent e) { 
  20.               System.out.println("window closed."); 
  21.               super.windowClosed(e); 
  22.           } 
  23.  
  24.       }); 
  25.       frame.setSize(new Dimension(5001000)); 
  26.       frame.setVisible(true); 

 

 

 

 本文转自 tianya23 51CTO博客,原文链接:http://blog.51cto.com/tianya23/499910,如需转载请自行联系原作者

相关文章
|
27天前
|
设计模式 SQL 算法
设计模式了解哪些,模版模式
设计模式了解哪些,模版模式
21 0
|
2月前
|
设计模式 Java uml
C++设计模式之 依赖注入模式探索
C++设计模式之 依赖注入模式探索
44 0
|
4月前
|
设计模式 存储 算法
Java 设计模式最佳实践:三、行为模式
Java 设计模式最佳实践:三、行为模式
22 0
|
3月前
|
设计模式 前端开发 JavaScript
观察者模式 vs 发布-订阅模式:两种设计模式的对决!
欢迎来到前端入门之旅!这个专栏是为那些对Web开发感兴趣、刚刚开始学习前端的读者们打造的。无论你是初学者还是有一些基础的开发者,我们都会在这里为你提供一个系统而又亲切的学习平台。我们以问答形式更新,为大家呈现精选的前端知识点和最佳实践。通过深入浅出的解释概念,并提供实际案例和练习,让你逐步建立起一个扎实的基础。无论是HTML、CSS、JavaScript还是最新的前端框架和工具,我们都将为你提供丰富的内容和实用技巧,帮助你更好地理解并运用前端开发中的各种技术。
|
24天前
|
设计模式 Java 数据库
小谈设计模式(2)—简单工厂模式
小谈设计模式(2)—简单工厂模式
|
4天前
|
设计模式 前端开发 Java
19:Web开发模式与MVC设计模式-Java Web
19:Web开发模式与MVC设计模式-Java Web
13 4
|
8天前
|
设计模式 消息中间件 Java
Java 设计模式:探索发布-订阅模式的原理与应用
【4月更文挑战第27天】发布-订阅模式是一种消息传递范式,被广泛用于构建松散耦合的系统。在 Java 中,这种模式允许多个对象监听和响应感兴趣的事件。
25 2
|
12天前
|
设计模式 存储 JavaScript
[设计模式Java实现附plantuml源码~创建型] 多态工厂的实现——工厂方法模式
[设计模式Java实现附plantuml源码~创建型] 多态工厂的实现——工厂方法模式
|
12天前
|
设计模式 Java Go
[设计模式Java实现附plantuml源码~创建型] 集中式工厂的实现~简单工厂模式
[设计模式Java实现附plantuml源码~创建型] 集中式工厂的实现~简单工厂模式
|
14天前
|
设计模式
设计模式(一)简单工厂模式
设计模式(一)简单工厂模式
14 0