设计模式之适配器模式

适配器模式(Adapter):将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类一起工作。

在软件开发中,适配器模式用来解决的这样的问题:系统的数据和行为都正确,但接口不符合我们的需求,此时,我们可能需要使用适配器模式,目的是使控制范围之外的一个原有对象与某个接口匹配。

在GOF的设计模式中,适配器模式分为类适配器模式、对象适配器模式、接口适配器模式,我们具体学习下这三种适配器模式。

一、适配器模式

1.1 、类的适配器模式

类的适配器模式的核心思想是:有一个Source类,拥有一个方法,待适配。目标接口是Target,通过Adapter类,将Source的功能扩展到Target中。其UML图如下:

这里写图片描述

类的适配器模式由以下部分组成:

目标角色(Target):这个目标不可以是类,必须是接口

源角色(Source):需要适配的类。

适配器角色(Adapter):适配器把源接口转换为目标接口,这个角色不可以是接口,必须是具体类,该类继承Source,实现Target接口。

代码部分

class Source{
    public void operation1(){
        System.out.println("我是等待适配的方法");
    }
}

interface Target{
    public void operation1();
    public void operation2();
}

class Adapter extends Source implements  Target{

    @Override
    public void operation2() {
        System.out.println("仅仅实现接口的一个方法");
    }
}

public class Test1 {
    public static void main(String[] args) {
        Adapter adapter = new Adapter();
        adapter.operation1();
        adapter.operation2();
    }
}

运行结果:

这里写图片描述

1.2、对象的适配器模式

对象的适配器模式和类的适配器模式相同,只是将Adapter类做修改,不继承Source,而是持有Source的实例。其UML图如下:
这里写图片描述

代码部分,只需要修改Adapter:

class Adapter  implements  Target{
    private Source source;

    public Adapter(Source source) {
        this.source = source;
    }

    @Override
    public void operation1() {
        source.operation1();
    }

    @Override
    public void operation2() {
        System.out.println("仅仅实现接口的一个方法");
    }
}
//客户端调用:
public class Test2 {
    public static void main(String[] args) {
        Source source = new Source();
        Adapter adapter = new Adapter(source);
        adapter.operation1();
        adapter.operation2();
    }
}

运行结果:

这里写图片描述

1.3 接口的适配器模式

当我们写一个有多个方法的接口的实现类时,不得不实现其所有的方法。但其实并不是所有的方法都是我们需要的。而接口的适配器模式,可以借助一个抽象类,实现该接口,我们只要实现这个抽象类就好了,其UML图如下:
这里写图片描述

代码部分:

interface Sourceable {
    public void operation1();

    public void operation2();
}

abstract class Source implements Sourceable {
    public void operation1() {}
    public void operation2() {}
}


class AdapterA extends Source {

    public void operation1() {
        System.out.println("我只想实现operation1方法");
    }

}


class AdapterB extends Source {

    public void operation2() {
        System.out.println("我只想实现operation2方法");
    }

}

class AdapterC extends Source {

    public void operation1() {
        System.out.println("我乐意实现operation1方法");
    }

    public void operation2() {
        System.out.println("我也可以实现operation2方法");
    }
}

public class Test3 {
    public static void main(String[] args) {
        AdapterA a1 = new AdapterA();
        AdapterB a2 = new AdapterB();
        AdapterC a3 = new AdapterC();

        a1.operation1();
        a1.operation2();

        a2.operation1();
        a2.operation2();

        a3.operation1();
        a3.operation2();
    }
}

运行结果:

这里写图片描述

二、案列分析

《西游记》中第五十九回《唐三藏路阻火焰山 孙行者一调芭蕉扇》中,师徒四人来到火焰上,要借铁扇公主的扇子扇灭火焰山的熊熊大火,孙悟空是没有这个功能的,借了三回也没借来。最后还是观音菩萨解的难。

假若我们想让孙悟空既能七十二变化,又能扇灭熊熊大火,岂不是大圣就把这事儿办了么?在适配器模式中,就很容易做到。其UML图如下:
这里写图片描述

代码部分


class TieShan{
    public void windly(){
        System.out.println("只有我铁扇公主才能扇灭火");
    }
}

interface Target{
    public void windly();
    public void change();
}

class Monkey extends TieShan implements  Target{

    @Override
    public void change() {
        System.out.println("老孙会七十二变");
    }
}

public class Test4 {
    public static void main(String[] args) {
        Monkey monkey = new Monkey();
        monkey.change();
        monkey.windly();
    }
}

运行结果:

这里写图片描述

从结果看,明明调用的是孙悟空,但也能扇灭火焰山的熊熊大火了。

所有示例代码地址:Adapter

三、模式结语

三种适配器的适用场景

  • 当一个类转换成满足另一个新接口的类时,可以使用类的适配器模式,创建一个新的类,继承原有的类,实现新的接口即可。

  • 当一个类转换成满足另一个新接口的对象时,可以使用对象的适配器模式,创建一个Adapter类,持有原类的一个实例 ,调用该实例的方法。

  • 当不希望实现一个接口中的所有方法时,可以创建一个抽象类,实现所有方法,在用新的类来继承抽象类即可。

欢迎大家留言评论,点击查看其它设计模式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值