设计模式(6):适配器模式

一、概念

1、定义:将一个类的接口转换成客户期望的另一个接口,让原本接口不兼容的类兼容

2、类型:结构型

3、适用环境

  • 已经存在的类,它的方法和需求不匹配时(比如我们想要复用一些现有的类,它只是接口不符合,就可以用适配器模式)
  • 不是软件设计阶段去考虑的设计模式,而是随着软件维护,不同产品、不同厂家造成功能类似而接口不同情况下的解决方案。

4、优缺点

优点

  • 把目标类和适配者类解耦,提高扩展性
  • 符合OCP,可以在原有代码基础上增加新的适配器
  • 具体的实现封装在适配者类中,对于客户端类来说是透明的(就是客户端感受不到)

缺点

  • 适配器在编写时要全面考虑,会增加系统复杂性
  • 增加代码可读难度,接口调接口,读起来困难

5、两种适配器

  • 对象适配器
    • 符合组合复用原则,使用委托机制(优先使用组合而不是继承)
      在这里插入图片描述
  • 类适配器
    • 通过类继承来实现
      在这里插入图片描述
      在这里插入图片描述

6、相关设计模式

  • 适配器和装饰者模式

    意图不一样,适配器是将一个类的接口转换成客户期望的接口,而装饰者是给被装饰者动态的增加职责,用于扩展功能。

  • 适配器和外观模式

    外观模式是定义一个新的接口,适配器是复用原有的接口;适配器使两个已有的接口协同工作,外观是提供更为方便的访问入口。

二、Coding

类适配器,通过继承实现

// 被适配者
public class Adaptee {
    public void adapteeRequest(){
        System.out.println("被适配者的方法");
    }
}
// 目标
public interface Target {
    void request();
}
public class ConcreteTarget implements Target {
    @Override
    public void request() {
        System.out.println("concreteTarget目标方法");
    }
}
// 适配者 通过 适配 被适配者 达到target目标
public class Adapter extends Adaptee implements Target{
    @Override
    public void request() {
        // 通过Adapter,把被适配者的方法 适配给了Target
        super.adapteeRequest();
        //...
    }
}

//Test
public class Test {

    public static void main(String[] args) {
        Target target = new ConcreteTarget();
        target.request();

        Target adapterTarget = new Adapter();
        //实现通过Adapter来实现
        adapterTarget.request();
    }
}
//concreteTarget目标方法
//被适配者的方法

在这里插入图片描述
对象适配器,通过组合实现

// 被适配者
public class Adaptee {
    public void adapteeRequest(){
        System.out.println("被适配者的方法");
    }
}
// 目标
public interface Target {
    void request();
}
public class ConcreteTarget implements Target {
    @Override
    public void request() {
        System.out.println("concreteTarget目标方法");
    }
}
// 适配者,直接实现Target
public class Adapter implements Target {
    //没有继承,无法调用父类方法,要把Adaptee组合过来,再调用
    private Adaptee adaptee;

    public Adapter(Adaptee adaptee) {
        this.adaptee = adaptee;
    }

    @Override
    public void request() {
        // 把具体实现Target的request方法委托给Adaptee来实现
        // ...
        adaptee.adapteeRequest();
        // ...
    }
}

在这里插入图片描述

三、双向适配器

设计和实现一个双向适配器实例,使得猫Cat可以学狗Dog叫Cry() ,狗可以学猫抓老鼠CatchMouse()

public interface Cat {
    void catchMouse();
}

public class ConcreteCat implements Cat {
    @Override
    public void catchMouse() {
        System.out.println("捉老鼠...");
    }
}

public interface Dog {
    void bark();
}

public class ConcreteDog implements Dog {
    @Override
    public void bark() {
        System.out.println("汪汪汪...");
    }
}

public class Adapter implements Cat,Dog{
    private ConcreteCat concreteCat;
    private ConcreteDog concreteDog;

    public Adapter(ConcreteCat concreteCat) {
        this.concreteCat = concreteCat;
    }

    public Adapter(ConcreteDog concreteDog) {
        this.concreteDog = concreteDog;
    }

    @Override
    public void catchMouse() {
        concreteDog.bark();
    }

    @Override
    public void bark() {
        concreteCat.catchMouse();
    }
}

public class Test {
    public static void main(String[] args) {
        Cat cat = new Adapter(new ConcreteDog());
        cat.catchMouse();

        Dog dog = new Adapter(new ConcreteCat());
        dog.bark();
    }
}

在这里插入图片描述

发布了43 篇原创文章 · 获赞 6 · 访问量 3907

猜你喜欢

转载自blog.csdn.net/weixin_44424668/article/details/103259504