结构型设计模式---适配器模式

1.定义

适配器模式,即定义一个包装类,用于包装不兼容接口的对象

包装类 = 适配器Adapter;
被包装对象 = 适配者Adaptee = 被适配的类

2.主要的作用

把一个类的接口变换成客户端所期待的另一种接口,从而使原本接口不匹配而无法一起工作的两个类能够在一起工作。

适配器模式的形式分为:类的适配器模式对象的适配器模式

3. 解决的问题

原本由于接口不兼容而不能一起工作的那些类可以在一起工作。

4. 原理

4.1.类图

  • 解决方案:为使Target能够使用Adaptee类里的SpecificRequest方法,故提供一个中间环节Adapter类(继承Adaptee & 实现Target接口),把Adaptee的API与Target的API衔接起来(适配)。

 4.2步骤

步骤1: 创建Target接口

public interface Target {
 
    //这是源类Adapteee没有的方法
    public void Request(); 
}

步骤2: 创建源类(Adaptee) ;

public class Adaptee {
    
    public void SpecificRequest(){
    }
}

步骤3: 创建适配器类(Adapter)

//适配器Adapter继承自Adaptee,同时又实现了目标(Target)接口。
public class Adapter extends Adaptee implements Target {

    //目标接口要求调用Request()这个方法名,但源类Adaptee没有方法Request()
    //因此适配器补充上这个方法名
    //但实际上Request()只是调用源类Adaptee的SpecificRequest()方法的内容
    //所以适配器只是将SpecificRequest()方法作了一层封装,封装成Target可以调用的Request()而已
    @Override
    public void Request() {
        this.SpecificRequest();
    }

}

步骤4:定义具体使用目标类,并通过Adapter类调用所需要的方法从而实现目标

public class AdapterPattern {

    public static void main(String[] args){

        Target mAdapter = new Adapter();
        mAdapter.Request();
     
    }
}

5.案例

  • 进口电视机要求电压(110V)与国内插头标准输出电压(220V)不兼容
  • 解决方案:设置一个适配器将插头输出的220V转变成110V

5.1使用步骤


步骤1: 创建Target接口(期待得到的插头):能输出110V(将220V转换成110V)

 public interface Target {

    //将220V转换输出110V(原有插头(Adaptee)没有的)
    public void Convert_110v();
}

步骤2: 创建源类(原有的插头) ;

class PowerPort220V{
//原有插头只能输出220V
    public void Output_220v(){
    }
}

步骤3:创建适配器类(Adapter)

class Adapter220V extends PowerPort220V implements Target{
   //期待的插头要求调用Convert_110v(),但原有插头没有
    //因此适配器补充上这个方法名
    //但实际上Convert_110v()只是调用原有插头的Output_220v()方法的内容
    //所以适配器只是将Output_220v()作了一层封装,封装成Target可以调用的Convert_110v()而已

    @Override
    public void Convert_110v(){
      this.Output_220v;
    }
}

步骤4:定义具体使用目标类,并通过Adapter类调用所需要的方法从而实现目标(不需要通过原有插头)

//进口机器类
class ImportedMachine {

    @Override
    public void Work() {
        System.out.println("进口机器正常运行");
    }
}


//通过Adapter类从而调用所需要的方法
public class AdapterPattern {
    public static void main(String[] args){

        Target mAdapter220V = new Adapter220V();
        ImportedMachine mImportedMachine = new ImportedMachine();
       
        //用户拿着进口机器插上适配器(调用Convert_110v()方法)
        //再将适配器插上原有插头(Convert_110v()方法内部调用Output_220v()方法输出220V)
        //适配器只是个外壳,对外提供110V,但本质还是220V进行供电
        mAdapter220V.Convert_110v();
        mImportedMachine.Work();
    }
}

6.实验题:

  1. 实现一个双向适配器实例,使得猫(Cat)可以学狗(Dog)叫,狗可以学猫抓老鼠。绘制相应类图并使用代码编程模拟。
interface Cat {
    public void play();
}
class concrectCat implements Cat{
    public void play(){
        System.out.println("猫捉老鼠");
    }
}
interface Dog {
    public void cry();
}
class concrectDog implements Dog{
    public void cry(){
        System.out.println("狗叫");
    }
}
class twowayAdapter implements Cat, Dog {
    private Cat cat;
    private Dog dog;

    public twowayAdapter(Cat cat) {
        this.cat = cat;
    }

    public twowayAdapter(Dog dog) {
        this.dog = dog;
    }

    public void cry() {
        cat.play();
    }

    public void play() {
        dog.cry();
    }

}
public class Test {
    // 客户端代码
    public static void main(String[] args) {
        System.out.println("狗学");
        Cat cat = new concrectCat();
        Dog dog = new twowayAdapter(cat);
        dog.cry();
        System.out.println("猫学");
        Dog dog1 = new concrectDog();
        Cat cat1 = new twowayAdapter(dog1);
        cat1.play();
    }
}

猜你喜欢

转载自blog.csdn.net/h18377528386/article/details/125173249