`

适配器模式之对象适配器

阅读更多

 问题导入:比如有A型螺母和B型螺母,那么用户可以再A型螺母上直接使用按着A型螺母生产的A型螺丝,同样也可以在B型螺母上直接使用按着B型螺母标准生产的B型螺丝。但是由于A型螺母和B型螺母的标准不一样,用户在A型螺母上不能直接使用B型的螺丝,反之也一样。该如何达到这个目的呢?

  使用适配器就可以解决这个问题:生产一种“A型螺母适配器”,这种A型螺母适配器的前端符合A型螺母标准要求,可以拧在A型螺母上,后端又焊接了一个B型螺母。这样用户就可以借助A型螺母适配器在A型螺母上使用B型的螺丝了。

  适配器模式又称为包装器,是用来将一个类的接口转换成客户希望的另外一个接口。这可以使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。适配器模式的关键是建立一个适配器,这个适配器实现了目标接口并且包含了被适配者的引用。

  适配器模式的三种角色:

  一、目标:目标是一个接口,该接口是客户想要使用的接口。

  二、被适配者:被适配者是一个已经存在的接口或抽象类,这个接口接口或者抽象类需要适配。

  三、适配器:适配器是一个类,该类实现了目标接口并且包含有被适配者的引用,即适配器的职责是对适配者接口或抽象类与目标接口进行适配。

  以下通过一个简单的问题来描述适配器模式中所涉及的各个角色。

  用户已经有一个两厢的插座,但是最近用户又有了一个新的三厢插座。用户现有一台洗衣机和一台电视机,洗衣机是三厢插头,而电视机是两厢插头。现在用户想用心的三厢插座来使用洗衣机和电视机,即用心的三厢插座为洗衣机和电视机接通电流。

  针对以上问题,使用适配器模式设计若干个类。

  1.目标

  本问题是使用三厢插座来为电视机和洗衣机接通电流,所以目标是三厢插座。把三厢插座设置为一个接口:

1 package com.adatpe;
2 
3 //适配目标:三相插座
4 public interface ThreeElectricOutlet {
5     void connectElectricCurrent();
6 }

  2.被适配者

  对于本问题,用户是想要用三厢插座为两厢插头的电视机接通电流,所以被适配者应该是两厢插座,也设置为一个接口:

1 package com.adatpe;
2 
3 //被适配者:两相插座
4 public interface TwoElectricOutlet {
5     void connectElectricCurrent();
6 }

  3.适配器

  该适配器实现了目标接口三厢插座ThreeElectricOutlet,同时又包含了两厢插座TwoElectricOutlet的引用:

复制代码
 1 package com.adatpe;
 2 
 3 //适配器:实现目标接口
 4 public class ThreeElectricAdapter implements ThreeElectricOutlet {
 5     //适配器包含被适配者的引用
 6     private TwoElectricOutlet outlet;
 7     public ThreeElectricAdapter(TwoElectricOutlet outlet) {
 8         this.outlet = outlet;
 9     }
10     public void connectElectricCurrent() {
11         outlet.connectElectricCurrent();
12     }
13 
14 }
复制代码

  下列应用程序中,Application.java使用了适配器模式中所涉及的类,应用程序负责用Wash类创建一个对象来模拟一台洗衣机,使用TV类创建一个对象来模拟一台电视机

使用ThreeElectricOutlet接口变量调用Wash对象的connectElectricCurrent()方法,并借助适配器调用TV对象的connectElectricCurrent()方法,即用三厢插座分别为洗衣机和电视机接通电流。

  

复制代码
 1 package com.adatpe;
 2 
 3 public class Application {
 4     public static void main(String[] args) {
 5         ThreeElectricOutlet outlet; //目标接口(三相插座)
 6         Wash wash = new Wash();     //洗衣机
 7         outlet = wash;              //洗衣机插在三相插座上
 8         System.out.println("使用三相插座接通电流");
 9         outlet.connectElectricCurrent();    //接通电流开始洗衣服
10         TV tv = new TV();           //电视机
11         ThreeElectricAdapter adapter = new ThreeElectricAdapter(tv); //把电视插在适配器上面
12         outlet = adapter;           //再把适配器插在三厢插座上
13         System.out.println("使用三厢插座接通电流");
14         outlet.connectElectricCurrent();  //接通电流,开始播放电视节目
15     }
16 }
17 
18 //洗衣机使用三相插座
19 class Wash implements ThreeElectricOutlet{
20     private String name;
21     public Wash() {
22         name = "黄河洗衣机";
23     }
24     public Wash(String name){
25         this.name = name;
26     }
27     public void connectElectricCurrent() {
28         turnOn();
29     }
30     public void turnOn(){
31         System.out.println(name+"开始洗衣服了");
32     }
33 }
34 
35 
36 //电视机使用两厢插座
37 class TV implements TwoElectricOutlet{
38     private String name;
39     public TV() {
40         name = "长江电视机";
41     }
42     public TV(String name){
43         this.name = name;
44     }
45     public void connectElectricCurrent() {
46         turnOn();
47     }
48     public void turnOn(){
49         System.out.println(name+"开始播放电视节目");
50     }
51     
52 }
复制代码

运行结果为:

使用三相插座接通电流
黄河洗衣机开始洗衣服了
使用三厢插座接通电流
长江电视机开始播放电视节目

 

下面举个双向适配器的例子

  在适配器模式中,如果Adapter角色同时实现目标接口和被适配者接口,并包含目标接口和被适配接口的引用,那么该适配器就是一个双向适配器。使用双向适配器,用户既可以用新的接口又可以用已有的接口。在以上例子中,如果用户希望能有三厢插座来接通洗衣机和电视机的电流,有可以用两厢插座来接通洗衣机和电视机的电流,那么就必须使用一个双向适配器。具体代码如下:

复制代码
 1 package com.adatpe;
 2 
 3 public class ThreeAndTwoElectricAdapter implements ThreeElectricOutlet,
 4         TwoElectricOutlet {
 5     private ThreeElectricOutlet threeElectricOutlet;
 6     private TwoElectricOutlet twoElectricOutlet;
 7     public ThreeAndTwoElectricAdapter(ThreeElectricOutlet threeOutlet,TwoElectricOutlet twoOutlet) {
 8         threeElectricOutlet = threeOutlet;
 9         twoElectricOutlet = twoOutlet;
10     }
11     public ThreeAndTwoElectricAdapter(TwoElectricOutlet twoOutlet,ThreeElectricOutlet threeOutlet){
12         threeElectricOutlet = threeOutlet;
13         twoElectricOutlet = twoOutlet;
14     }
15     public void connectElectricCurrent() {
16         if(this instanceof ThreeElectricOutlet){
17             twoElectricOutlet.connectElectricCurrent();//twoElectricOutlet是被适配的接口
18         }
19         if(this instanceof TwoElectricOutlet){
20             threeElectricOutlet.connectElectricCurrent(); //threeElectricOutlet是被适配的接口
21         }
22     }
23     public static void main(String[] args) {
24         ThreeElectricOutlet threeOutlet;
25         TwoElectricOutlet twOutlet;
26         Wash wash = new Wash();
27         TV tv = new TV();
28         ThreeAndTwoElectricAdapter adapter = new ThreeAndTwoElectricAdapter(wash,tv);
29         threeOutlet = adapter;
30         System.out.println("使用三厢插座接通电源");
31         threeOutlet.connectElectricCurrent();
32         twOutlet = adapter;
33         System.out.println("使用两厢插座接通电源");
34         twOutlet.connectElectricCurrent();
35     }
36 
37 }
复制代码


运行结果为:

使用三厢插座接通电源
长江电视机开始播放电视节目
黄河洗衣机开始洗衣服了
使用两厢插座接通电源
长江电视机开始播放电视节目
黄河洗衣机开始洗衣服了

这样就实现了即可以用三厢插座又可以用两厢插座来为电视机和洗衣机接通电流了。

使用适配器模式主要有以下优点:

  1.目标和被适配者是完全解耦的关系。

  2.适配器模式满足“开--闭原则”,当添加一个实现了Adapter接口的新类时,不必修改Adapter,Adapter就能对这个新类的实例进行适配。

 

分享到:
评论

相关推荐

    设计模式之适配器模式

    在Java中,适配器模式主要分为两种类型:类适配器模式和对象适配器模式。类适配器模式通过继承目标接口和被适配者类来实现,而对象适配器模式则通过包含被适配者对象并实现目标接口来完成适配过程。 1. 类适配器...

    设计模式之适配器模式Java实现和类设计图

    在这个Java实现中,我们将深入探讨适配器模式的两大类型:类适配器模式和对象适配器模式,并通过具体的代码示例和UML类图来阐述其工作原理。 首先,我们来理解适配器模式的基本概念。适配器模式就像现实生活中的...

    java设计模式之适配器模式

    适配器模式可以分为类适配器和对象适配器两种类型。 1. 类适配器:适配器类继承自目标接口,并且包含一个被适配类的实例。 2. 对象适配器:适配器类通过组合的方式包含被适配类的引用,而不是继承。 二、适配器...

    JAVA设计模式(抽象类与适配器模式)

    在Java中,适配器模式有两种形式:类适配器和对象适配器。类适配器模式通过继承目标接口和适配者类来实现,而对象适配器模式则是通过组合适配者类来实现。适配器模式常用于旧系统改造或者第三方库的接口调整,它降低...

    设计模式 - 适配器模式(C++实例)

    在C++中,适配器模式主要有两种实现方式:类适配器和对象适配器。类适配器模式是通过多重继承来实现的,而对象适配器模式则通过组合来实现。下面我们详细探讨这两种方式。 1. 类适配器模式: 在类适配器模式中,...

    类适配器, 对象适配器模式,缺省适配器模式1

    适配器模式分为类适配器模式和对象适配器模式,还有缺省适配器模式。 1. **类适配器模式**: 在类适配器模式中,适配器类通过继承被适配类(Adaptee)并实现目标接口(Target)。这种方式下,适配器和被适配类之间...

    java中适配器模式案例

    这些示例可能包括类适配器和对象适配器两种形式,展示如何在实际项目中应用该模式。 在"Adapter.java"文件中,可能是适配器类的源代码实现,包含目标接口的实现以及对被适配类方法的调用和结果转换。通过阅读这个...

    适配器模式实例之算法适配

    适配器模式在软件开发中主要分为三种实现方式:类适配器、对象适配器和缺省适配器。 类适配器模式通过继承被适配的类和实现目标接口来实现适配。这种方式下,适配器直接继承了被适配者的接口,然后实现所需的接口。...

    Java设计模式之适配器模式

    ### Java设计模式之适配器模式详解 #### 引言 在软件开发中,我们经常遇到需要使用已有的类库,但这些类库的接口与我们的需求不匹配的情况。这时,适配器模式(Adapter Pattern)便能派上用场。适配器模式是一种...

    java 动态代理模式 适配器模式

    适配器模式主要有类适配器和对象适配器两种形式。类适配器模式通过继承目标接口和适配类来实现,而对象适配器模式则通过包含适配类对象并实现目标接口来达到目的。适配器模式使得旧的代码可以与新的系统无缝对接,...

    适配器模式案例代码

    适配器模式主要有两种形式:类适配器模式和对象适配器模式。在类适配器模式中,适配器类继承自目标接口,并包含一个原始不兼容接口的对象。而在对象适配器模式中,适配器类通过组合(拥有)原始接口的对象来实现目标...

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

    适配器模式有类适配器和对象适配器两种形式。类适配器模式通过继承来实现适配,适配器类继承自原始类并实现目标接口;对象适配器模式则通过组合来实现,适配器类包含一个原始类的对象,并实现目标接口。 适配器模式...

    设计模式系列之适配器模式

    适配器模式主要分为三类:类适配器、对象适配器和接口适配器,但最常见的实现是对象适配器。 在类适配器模式中,适配器本身是一个类,它继承自目标接口,并且包含对原始类的引用。由于继承的限制,这种模式在多继承...

    设计模式-适配器模式(讲解及其实现代码)

    适配器模式有三种主要形式:类适配器模式、对象适配器模式和接口适配器模式。 1. 类适配器模式:适配器类继承自原始接口或类,并实现新的目标接口。这种方式适用于目标接口和原始接口都是类的情况,但缺点是如果...

    适配器模式源代码

    适配器模式主要有三种形式:类适配器、对象适配器和接口适配器。在这个实例中,我们可能会看到其中的一种或多种形式的实现。 1. 类适配器模式:适配器类直接继承被适配者,并实现目标接口。这种方式下,适配器和被...

    适配器模式demo源码

    在Java或其他面向对象语言中,适配器模式通常有两种形式:类适配器和对象适配器。 1. 类适配器模式:通过继承目标接口并包含(或组合)原始类来实现。这种方式在Java中受限于单继承特性,因此使用相对较少。 2. ...

Global site tag (gtag.js) - Google Analytics