设计模式学习笔记——适配器模式/外观模式

适配器模式

定义:将一个类的接口,转换成客户期望的另一个接口。适配器让原本接口不兼容的类可以合作无间。

代码示例

旧系统使用接口A,现在接口升级,需求接口B。
1、旧接口

public interface InterfaceA {
    void execute();
    void undo();
}

2、旧接口实体类

public class ConcretedClassA implements InterfaceA {
    @Override
    public void execute() {
        System.out.println("具体类A执行");
    }

    @Override
    public void undo() {
        System.out.println("具体类A撤销");
    }
}

3、代码升级,采用接口B

public interface InterfaceB {
    void executeB();

    void undoB();
}

实现新的接口B举例:

public class ConcretedClassB implements InterfaceB {
    @Override
    public void executeB() {
        System.out.println("具体类B执行");
        System.out.println("具体类B执行");
    }

    @Override
    public void undoB() {
        System.out.println("具体类B撤销");
        System.out.println("具体类B撤销");
    }
}

4、编写适配器类(进行接口转换A->B)

public class AdapterA2B implements InterfaceB {
    private InterfaceA interfaceA;

    public AdapterA2B(InterfaceA interfaceA) {
        this.interfaceA = interfaceA;
    }

    @Override
    public void executeB() {
        interfaceA.executeA();
        interfaceA.executeA();
    }

    @Override
    public void undoB() {
        interfaceA.undoA();
        interfaceA.undoA();
    }
}

适配器,持有实现接口A的对象引用,利用内部代码转换成接口B的方法。从而让客户代码可以用该适配器对象(模拟实现接口B的对象)。
5、客户代码

    public static void main(String[] args) {
        InterfaceA a = new ConcretedClassA();
        //现在客户需要使用接口B,但旧系统使用的是接口A,不希望改变旧接口
        // 通过适配器可以将A包装成B
        InterfaceB b = new AdapterA2B(a);
        execute(b);
    }

    public static void execute(InterfaceB interfaceB) {
        interfaceB.executeB();
        interfaceB.undoB();
    }

对于客户代码来说,execute方法只需要参数实现InterfaceB,通过适配器把A包装成B,进而可以使用。

说明

我们把接口A和接口B的变化封装在适配器内部。

类图

这里写图片描述
客户代码需求实现Target接口的类,而我们只有Adaptee类;使用适配器,把Adaptee封装成实现Target接口的类,从而客户代码可以间接使用Adaptee。
上述代码示例,Client就是Main函数,Target就是InterfaceB,Adapter是AdapterA2B,Adaptee是InterfaceA。


外观模式

定义:提供了一个统一的接口,用来访问子系统中的一群接口。外观定义了一个高层接口,让子系统更容易使用。(类似于一键XX,一键开启之类的)

示例代码

public class AllFacade{
    A a;
    B b;
    C c;
    D d;
    public AllFacade(A a,B b,C c,D d){
        this.a=a;
        this.b=b;
        this.c=c;
        this.d=d;
    }
    public void execute(){
        a.execute();
        b.execute();
        c.execute();
        d.execute();
    }
    //public void fun....
}

类图

这里写图片描述

说明

  • 通过一个外观类(接口)将复杂的子系统操作过程,封装成简便的方法对外暴露,供客户使用起来比较方便。
  • 外观将客户从一个复杂的子系统中解耦。
  • 实现一个外观,需要将子系统组合进外观中,然后将工作委托给子系统执行。

适配器、外观、装饰者的区别

适配器:将一个接口转换成另一个接口以改变接口,为了兼容性和避免修改原有代码。
外观:将一群接口(类)包装成一个接口(类)以简化接口,为了客户使用方便。
装饰者:将一个对象包装起来以增加新的行为和责任。


设计原则

最少知识原则

只和你的密友谈话
这个原则希望我们在设计中,不要让太多的类耦合在一起,免得修改系统中的一部分,会影响到其他部分。如果许多类之间相互依赖,那么这个系统就会变成一个易碎的系统,它需要花许多成本去维护,也会因为太复杂而不容易被其他人了解。

指导方针

就任何对象而言,在该对象的方法内部,我们只应该调用属于以下范围的方法:

  • 该对象本身
  • 被当做方法的参数而传递进来的对象
  • 此方法创建或实例化的任何对象
  • 对象的任何组件(把“组件”想象成是被实例变量的引用的任何对象,换言之,把这想象成是“有一个”(HAS-A)关系)

举例

不采用原则的方法:

public float getTemp(){
    Thermometer thermometer = station.getThermometer();
    return thermometer.getTemperature();
}

采用原则的方法:

public float getTemp(){
    return station.getTemperature();
}

采用原则的一个类:

public class Car{
    Engine engine; //组件
    public Car(){}
    public void start(Key key){ //被当做参数传进来的对象,其方法可以调用
        Doors doors = new Doors() //创建新的对象,它的方法可以被调用
        boolean authorized = key.turns();//被当做参数传进来的对象,其方法可以调用
        if(authorized){
            engine.start(); //可以调用组件的方法
            updateDashboardDisplay();//可以调用同一个对象内的本地方法
            doors.lock();//可以调用创建或实例化的对象的方法
        }
    }
    public void updateDashboardDisplay(){}
}

猜你喜欢

转载自blog.csdn.net/u012525096/article/details/80664066