《Head First 设计模式》读书笔记(7)——适配器模式与外观模式 Adapter and Facade

本文共2700词,阅读需要15分钟,本文相关代码地址被托管在 gitee,中间因为其他事情,20天才看完这一章,,,,

生活中的适配器

总所周知,在中国通用的电压时 220V,而美国电压则是 110V,如果有经常在美国和中国之间跑的 IT 人,而其笔记本都是随身携带的,那么它的笔记本的电压问题如何解决呢?

(因为在美国和中国电压不同,所以一般的电器会不通用的)而适配器在这个问题上体现得妙极妙极。
现在的笔记本都有一个电源适配器,而正是这个电源适配器来解决上面提到的适配器问题,比如,一款索尼笔记本,其输入电流为交流100V~240V,而输出则是统一的直流 19.5V,在电源适配器的一端输入交流电流,然后通过电源适配器把电源变成需要的电压,也就是适配器的作用是使得一个东西适合另外一个东西。

对比装饰者模式,装饰者是将对象包装起来,赋予他们新的指责;而现在是希望他们看起来是另外一样东西。

OO中的适配器

将一个接口转换成另外一个接口,符合最终的期望。
比如你现在的软件系统和别人实际的类无法搭配使用,但是你不想改变现有的系统,又不能改变别人的类,于是你可以写一个类将别人的接口转换成你要的接口

火鸡转换器

如果他走起来像只鸭子,叫起来像只鸭子,但是它有可能是只火鸡

策略模式中所有鸭子都来自有抽象的Duck,现在的火鸡按照规范你只能让他继承Tuckey,但是你可以添加TurkeyAdapter适配器

public class TurkeyAdapter implements Duck {
    Turkey turkey;

    public TurkeyAdapter(Turkey turkey) {
        this.turkey = turkey;
    }

    @Override
    public void quack() {
        turkey.gobble();
    }

    @Override
    public void fly() {
        turkey.fly();
    }
}

客户使用适配器的过程如下:

  1. 客户通过目标接口调用适配器的方法对适配器发出请求。
  2. 适配器使用被适配者接口把请求转换成被适配者的一个或多个调用接口。
  3. 客户接受到调用的结构,但并未察觉这一切是适配器在起转换作用。

重点就是适配器使用了目标的接口,并持有被适配器的实例。

个人总结:充电头还是充电头,还是要往那个插座上插,但是插不上,于是适配器和老充电头构成了新充电头,如果没人告述你这用了适配器,你会以为就是老充电头直接插上了。适配器要做的就是里面容纳老充电头(实例化一个对象),但是看起来又像是新充电头(继承新充电头)

适配器模式

适配器模式是将一个类的接口,转换成客户期望的另一个接口,让原本接口不兼容的类可以合作无间。
适配器需要做到的的工作就是实现目标接口的所有工作。
适配器本来只是将一个接口转换成另一个,但是很多情况是需要让一个适配器包装多个被适配者,这是外观模式。

类适配器(java无法多重继承,所以没法实现)和对象适配器

类适配器:继承

对象适配器:组合

OO设计原则第三条:多用组合,少用继承

真实例子

其实很多情况多是新旧代码冲突,但是给新接口添加适配器,让旧接口能够适配
比如JDK1.2以前的Enumaration接口和新的Iterator接口

装饰者 vs 适配器 vs 外观

装饰者是装饰者和被装饰者有相同的超类型,所以其并没有改变接口,只是一个接口在使用时给他添加了一些原来不属于他的功能。
适配器则是将旧接口直接包装了适配器接口,而适配器接口则实现了新接口。
而外观模式则是简化了接口,只显露了美好干净的外观。

外观模式

背景:建造自己的家庭影院

家庭影院不是只有一台DVD机那么简单,而是包含了灯光的调节、投影、立体声、自动屏幕甚至一些爆米花机榨汁机

你可以选择最笨的方法

对每个设备都使用一个类去控制,在使用一个主方法去调用实现。

但是这样问题在于,如果你把所有一切都关掉,你就要重新反向来一遍。
如果你只需要使用立体声欣赏音乐,又显得很累赘
所以你可以使用外观模式来避免这一切混乱,只是享受一场电影。

外观模式

你为家庭影院专门创建一个类,他对外暴露出几个简单的方法,例如看电影方法,调节音量方法等,然后就变成调用一堆子系统来操作,现在开始你不在直接去调节子系统具体的方法,而是一站式的感觉完成一系列的任务。
假如你还是想使用子系统的具体功能,你还是可以直接调用,外观模式等于做了一层高阶的隔离

可以为子系统创造不同的外观模式

和适配器模式的不同

不在于转换接口的数量,而是在于目的不一样,适配器希望改变接口来符合最后的期待,而外观模式是觉得子系统比较复杂,希望提供一站式的简化接口,同时也达到了从子类解耦的目的。

最少知识原则的关键

只调用下面几种东西:
对象本身,被当作方法的参数而传递进来的对象,此方法所创建或实例化的任何对象,对象的任何组件
如:
float a = station.getB().getA(); ==> float a = station.getA() 直接要在里面实现,不要调用的时候在去耦合很多类实现,或者将B直接实例化对象在进行调用。

这个原则的好处是维护起来方便,但是因为包装类有时很多余,开发不方便,运行可能会慢一点。

其实System.out.println()就违反了最少知识原则,但是很方便不是吗

发表评论

电子邮件地址不会被公开。