Object Adapter of Adapter Pattern

 Problem introduction: For example, if there are A-type nuts and B-type nuts, then the user can directly use the A-type screws produced according to the A-type nut on the A-type nut, and can also directly use the B-type nut according to the B-type nut standard. Production of B-type screws. However, due to the different standards of A-type nuts and B-type nuts, users cannot directly use B-type screws on A-type nuts, and vice versa. How to achieve this goal?

  This problem can be solved by using an adapter: produce an "A-type nut adapter", the front end of this A-type nut adapter meets the requirements of the A-type nut standard, and can be screwed on the A-type nut, and a B-type nut is welded at the rear end. . In this way, the user can use the B-type screw on the A-type nut with the A-type nut adapter.

  The adapter pattern, also known as a wrapper, is used to convert the interface of a class into another interface that the client wants. This allows classes that would otherwise not work together due to incompatible interfaces to work together. The key to the adapter pattern is to create an adapter that implements the target interface and contains a reference to the adapter.

  The three roles of the adapter pattern:

  1. Target: The target is an interface that the client wants to use.

  2. Adaptee: The adaptee is an existing interface or abstract class, and this interface interface or abstract class needs to be adapted.

  3. Adapter: An adapter is a class that implements the target interface and contains a reference to the adapter, that is, the adapter's responsibility is to adapt the adapter interface or abstract class to the target interface.

  The following describes the roles involved in the adapter pattern through a simple question.

  The user already has an outlet for the hatchback, but recently the user has a new outlet for the sedan. The user has a washing machine and a TV, the washing machine is a three-box plug, and the TV is a hatchback plug. Now users want to use the washing machine and TV with the intentional sedan socket, that is, the intentional sedan socket connects the washing machine and the TV with electricity.

  For the above problems, use the adapter pattern to design several classes.

  1. Goals

  This question is using a sedan socket to get electricity for the TV and washing machine, so the target is a sedan socket. Set the sedan socket as an interface:

1  package com.adatpe;
 2  
3  // Adaptation target: three-phase socket 
4  public  interface ThreeElectricOutlet {
 5      void connectElectricCurrent();
 6 }

  2. Adaptee

  For this problem, the user wants to use the sedan socket to connect the current to the TV with the hatchback plug, so the adapter should be the hatchback socket, which is also set as an interface:

1  package com.adatpe;
 2  
3  // Adapted : Two-phase outlet 
4  public  interface TwoElectricOutlet {
 5      void connectElectricCurrent();
 6 }

  3. Adapter

  The adapter implements the target interface ThreeElectricOutlet of the three-box socket, and also contains the reference of the hatchback socket 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就能对这个新类的实例进行适配。

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326354549&siteId=291194637