设计之禅——适配器模式

2020-09-07 10:43:32 浏览数 (1)

概述

对于适配器相信大家不会陌生,生活中有各种各样的例子,像耳机转接线,充电器适配器,水管适配接口等等。通过类比我们很容易理解适配器的作用:

将已有的本无法使用的类通过适配器转换,从而达到资源复用,节省开销的目的。

那要如何通过代码实现这一点呢?既然要将被适配者转换为目标接口类,那么适配器肯定是要实现自该接口的,以保证类型、行为的一致,但要如何转换呢?很简单,只需要通过继承或组合被适配者就能轻易的实现。注意基于多使用组合,少使用继承的原则,我们一般会选择组合的方式来实现,这种方式叫对象适配器,而通过继承实现的叫类适配器,后者一般用于一个适配器需要转换多个被适配者的情况;但Java中没有多继承,因此此处仅讨论对象适配器。类图如下:

Coding

小明有一台用肾换来的IPhone,某天IPhone的充电器坏了,但IPhone的充电器太贵,小明没钱买新的了,他想到之前的Android充电器还是好的,但是不兼容IPhone手机啊,不过小明知道网上有Android和IPhone的接口转换器卖,而且很便宜,立马就买了一个回来,完美解决,不用再卖肾了。我们就用代码来实现这个过程,首先是IPhone和Android: ···java public class IPhone {

代码语言:javascript复制
// 注意IPhone充电器现在是不能正常工作的
public void iPhoneCharging() {
    System.out.println("充电器坏了。。。");
}

}

public class Andriod {

代码语言:javascript复制
public void andriodCharging() {
    System.out.println("充电中....");
}

} ··· 可以看到这两个东西完全没有关联,但小明需要Android充电器和IPhone充电器一样为IPhone充电:

代码语言:javascript复制
public class AndriodAdatper extends IPhone {

    private Andriod andriod;

    public AndriodAdatper(Andriod andriod) {
        this.andriod = andriod;
    }

    @Override
    public void iPhoneCharging() {
        andriod.andriodCharging();
    }

}

有了这个适配器小明就可以正常充电了:

代码语言:javascript复制
public class XiaoMing {

    public static void main(String[] args) {
        Andriod andriod = new Andriod();
        IPhone iPhone = new AndriodAdatper(andriod);
        iPhone.iPhoneCharging();
    }

}

实现适配器非常容易,通过上述代码,我们也可以看到被适配者对于客户端而言是完全透明的,具体需要适配什么也是由客户端来决定的,通过适配器就将现有的接口类和被适配者完全解耦了,但是我们也可以发现每当需要转换一个类时都需要一个适配器,这样就会导致系统结构变得非常复杂,因此使用时也需要格外注意。

小结

适配器模式可以将一个不兼容的类转化为可复用的类,这样可以使得我们不用添加额外冗余臃肿的代码,但同时也会产生许多的适配器类,也会增加系统的复杂性。同时,既然是转换不兼容的类,那么该模式应尽可能的用于项目后期的补偿,而不是初期的详细设计中,否则就应该好好考虑下初期设计是否合理。

0 人点赞