Head First设计模式读书笔记六 第七章下 外观模式

版权声明:本文为博主原创文章,转载请注明出处 https://blog.csdn.net/u011109881/article/details/82344097

本文示例代码材料源自Head First设计模式
以前整理自己整理的链接:
https://blog.csdn.net/u011109881/article/details/59153772

简介

Head First之所以把外观模式和适配器模式放在一起,是因为他们有共同点:他们都是由于当前对象无法满足当前需求,需要对其进行改造包装。这一点和装饰器模式也很类似。只不过他们的目的各有不同。
装饰器:对原对象进行包装,试图添加新功能
适配器:对原对象进行包装,试图使其表现得“像”另一种对象
外观:对一个或多个对象进行包装,使得对象使用者不需要了解详细的复杂内部接口和关系就可以简单的使用复杂的系统。
比如下面这个样子
这里写图片描述
或者这个样子
这里写图片描述
个人感觉,外观模式和命令模式中的升级版–批处理命令的思想很类似。
请参照:https://blog.csdn.net/u011109881/article/details/81915188
废话不多说,栗子证明一切。

外观模式简单示例

比如在家庭影院看电影这个例子(用投影仪投影电脑的电影),我们要做如下工作:
打开爆米花机
开始爆米花
灯光调暗
放下屏幕
打开投影仪
打开功放
设置功放效果为立体声
设置功放音量5
打开电脑
连接HDMI
播放电影

如果没有外观模式,情形是这样的:

bean:

public class Apm {
    int volume;
    public void on() {
        System.out.println("打开功放");
    }

    public void setSurroundSound() {
        System.out.println("设置立体声");
    }

    public void setVolume(int volume) {
        this.volume = volume;
        System.out.println("设置音量"+volume);
    }

    public void off() {
        System.out.println("关闭功放");
    }
}
public class Laptop {
    public void on() {
        System.out.println("打开笔记本");
    }

    public void connect() {
        System.out.println("连接HDMI以投影");
    }

    public void playMovie(){
        System.out.println("播放--天空之城");
    }

    public void off() {
        System.out.println("关闭笔记本");
    }
}
public class Light {
    int lightPercent;
    public void dim(int percent) {
        this.lightPercent = percent;
        System.out.println("亮度调节为 "+percent+" %");
    }

    public void normal() {
        this.lightPercent = 100;
        System.out.println("亮度调节正常亮度");
    }
}
public class Poper {
    public void on() {
        System.out.println("打开爆米花机");
    }

    public void pop() {
        System.out.println("开始爆米花");
    }
    public void off() {
        System.out.println("关闭爆米花机");
    }

}

public class Projector {
    public void on() {
        System.out.println("打开投影仪");
    }

    public void off() {
        System.out.println("关闭投影仪");
    }
}
public class Screen {
    public void down() {
        System.out.println("screen down");
    }

    public void up() {
        System.out.println("收起屏幕");
    }
}

test类:

public class Test {

    public static void main(String[] args) {
        Apm apm = new Apm();
        Laptop laptop = new Laptop();
        Light light = new Light();
        Poper poper = new Poper();
        Projector projector = new Projector();
        Screen screen = new Screen();

        poper.on();
        poper.pop();
        light.dim(10);
        screen.down();
        projector.on();
        apm.on();
        apm.setSurroundSound();
        apm.setVolume(5);
        laptop.on();
        laptop.connect();
        laptop.playMovie();
    }

}

测试结果

打开爆米花机
开始爆米花
亮度调节为 10 %
screen down
打开投影仪
打开功放
设置立体声
设置音量5
打开笔记本
连接HDMI以投影
播放--天空之城

有了外观模式,情形是这样的:

首先需要添加外观接口类:

public class Facade {
    Apm apm;
    Laptop laptop;
    Light light;
    Poper poper;
    Projector projector;
    Screen screen;

    public Facade(Apm apm, Laptop laptop, Light light, Poper poper,
            Projector projector, Screen screen) {
        this.apm = apm;
        this.laptop = laptop;
        this.light = light;
        this.poper = poper;
        this.projector = projector;
        this.screen = screen;
    }

    public void playMovie(){
        poper.on();
        poper.pop();
        light.dim(10);
        screen.down();
        projector.on();
        apm.on();
        apm.setSurroundSound();
        apm.setVolume(5);
        laptop.on();
        laptop.connect();
        laptop.playMovie();
    }

    public void endPlayMovie() {
        poper.off();
        light.normal();
        screen.up();
        projector.off();
        apm.off();
        laptop.off();
        laptop.disconnect();
    }
}

其次,测试类需要改写

public class Test {

    public static void main(String[] args) {
        Apm apm = new Apm();
        Laptop laptop = new Laptop();
        Light light = new Light();
        Poper poper = new Poper();
        Projector projector = new Projector();
        Screen screen = new Screen();

        Facade facade = new Facade(apm, laptop, light, poper, projector, screen);
        facade.playMovie();
        facade.endPlayMovie();
    }

测试结果:

打开爆米花机
开始爆米花
亮度调节为 10 %
screen down
打开投影仪
打开功放
设置立体声
设置音量5
打开笔记本
连接HDMI以投影
播放--天空之城
关闭爆米花机
亮度调节正常亮度
收起屏幕
关闭投影仪
关闭功放
关闭笔记本
断开HDMI

结论

外观模式可以创建一个简单和统一的类,用于包装子系统的一个或多个复杂的类,使得客户端和复杂子系统进行解耦。

几点其他要点

1.外观模式不进行封装:
外观模式只是对原有系统进行简单的接口组合,但是不进行封装。客户端仍然可以直接访问原系统,如果客户端觉得有必要的话。
2.一个系统可以提供多个外观接口,以适应各种客户端。
3.外观能够实现将子系统和客户端解耦
4.减少对象间依赖—-最少知道原则:减少对象之间的交互,以降低耦合性。对于一个对象,我们如何才能做到最少知道原则呢?
对于一个对象,我们可以使用的部分应尽量限定在以下范围:
a对象本身
b该对象本身的任意组件(属性)
c作为参数传递过来的对象及其方法
d在该对象实例化或创建的对象及其方法
尽量不要主动获取对象或是调用主动得到的对象的方法

扫描二维码关注公众号,回复: 3340751 查看本文章

猜你喜欢

转载自blog.csdn.net/u011109881/article/details/82344097