HeadFirst-设计模式-外观模式

版权声明:来这世间走一遭总的留下点什么 https://blog.csdn.net/FightingITPanda/article/details/81251669

外观模式:提供了一个统一的接口,用来访问子系统中的一群接口,外观定义了一个高层接口,让子系统更容易使用。
外观模式实现了最少知识原则(Least Knowledge principle),这个原则希望不要让太多的类耦合在一起,对用户来说只和一个外观类打交道了,达到客户和一群子系统的解耦。


话不多说、上实例:
老外要实现以家庭影院,他要看电影的时候要依次做这些事:
1.打开爆米花机
2.开始蹦爆米花
3.将灯光调暗
4.放下屏幕
5.打开投影仪
6.将投影仪设置为宽屏模式
7.打开功放
8.将功放的输入设置为DVD
9.将功放设置为环绕立体声、
10.打开DVD播放器
11.开始播放DVD
他不想走到每个机器面前按下按钮,就是不想和每个类打交道,让我们给设置一个按钮,按一下即执行全部动作
上图
这里写图片描述
1.先来定义这些多媒体类

class Amplifier{
    public void on(){
        System.out.println("欢迎使用功放类。。");
    }
    public void off(){
        System.out.println("已经关闭功放。。");
    }
    public void setCD(){
        System.out.println("正在安放CD。。。");
    }
    public void setDVD(){
        System.out.println("正在安放DVD、。。");
    }
    public void setStereoSound(){
        System.out.println("设置立体声。。");
    }
    public void setSurroundSound(){
        System.out.println("设置环绕立体声。。");
    }
    public void setTime(){
        System.out.println("正在设置时间。。");
    }
    public void setVolume(){
        System.out.println("正在设置音量。。");
    }
}
//定义Tuner类
class Tuner{
    public void on(){
        System.out.println("正在 打开调谐器。。");
    }
    public void off(){
        System.out.println("正在关闭调谐器。。");
    }
    public void setAM(){
        System.out.println("正在设置am。。");
    }
    public void setFM(){
        System.out.println("正在设置频道。。");
    }
    public void setFrequency(){
        System.out.println("正咋设置频道。。");
    }
}
//定义DVD播放器类
class DVDPlayer{
    public void on(){
        System.out.println("正在打开DVD。。");
    }
    public void off(){
        System.out.println("正在关闭DVD。。");
    }
    public void pause(){
        System.out.println("已经暂停DVD播放。。");
    }
    public void play(){
        System.out.println("正在播放DVD。。");
    }
    public void setTwoChannelAudio(){
        System.out.println("正在设置双频道。。");
    }
    public void setSurroundAudio(){
        System.out.println("正在设置环绕立体声。。");
    }
}
//定义CD播放器
class CDPlayer{
    public void on(){
        System.out.println("正在打开CD");
    }
    public void off(){
        System.out.println("正在关闭CD");
    }
    public void eject(){
        System.out.println("eject 啥意思。。。");
    }
    public void pause(){

    }
    public void play(){

    }
    public String toString(){
        return "hello panda";
    }
}
//定义投影仪
class Projector{
    public void on(){
        System.out.println("正在打开投影仪。。");
    }
    public void off(){
        System.out.println("正在关闭投影仪。。");
    }
    public void setTVMode(){
        System.out.println("正在设置tv模式。。");
    }
    public void setWideScreenMode(){
        System.out.println("正在设置宽屏模式。。");
    }
}
//定义屏幕
class Screen{
    public void up(){
        System.out.println("正在生起屏幕。。");
    }
    public void down(){
        System.out.println("正在放下屏幕。。");
    }
}
//定义爆米花机
class PopcornPopper{
    public void on(){
        System.out.println("正在打开爆米花机。。");
    }
    public void off(){
        System.out.println("正在关闭爆米花机。。");
    }
    public  void pop(){
        System.out.println("正在蹦爆米花。。");
    }
}
//定义影院灯光
class TheaterLights{
    public void on(){
        System.out.println("正在打开灯光。。");
    }
    public void off(){
        System.out.println("正在关闭灯光。。");
    }
    public void dim(){
        System.out.println("正在调暗灯光。。");
    }
}

2.多媒体的具体类准备好就可以定义外观模式类了俩方法,一个看电影-打开一系列设备,一个电影结束-关闭一系列设备

//定义外观模式家庭影院
class HomeTheaterFacade{
    Amplifier amp;
    Tuner tuner ;
    DVDPlayer dvd;
    CDPlayer cd;
    Projector project;
    TheaterLights light;
    Screen screen;
    PopcornPopper pop;
    //构造的时候拿到这些对象
    public HomeTheaterFacade(Amplifier amp,Tuner tuner,DVDPlayer dvd,  
            CDPlayer cd ,Projector project,TheaterLights light,Screen screen 
            ,PopcornPopper pop){
        this.amp = amp;
        this.tuner = tuner;
        this.dvd = dvd;
        this.cd = cd;
        this.project = project;
        this.light  = light;
        this.screen = screen;
        this.pop = pop;
    }
    //看电影  放一个方法里来执行一系列动作
    public void watchMovie(String movie){
        System.out.println("get ready to watch a movie..");
        pop.on();//首先打开爆米花机
        pop.pop();//然后蹦爆米花
        light.dim();//把灯光调暗
        screen.down();//投影仪放下来
        project.on();
        project.setWideScreenMode();
        amp.on();
        amp.setDVD();
        amp.setSurroundSound();
        amp.setVolume();
        dvd.on();
        dvd.play();
    }
    //电影结束
    public void endMovie(String movie){
        System.out.println("shutting movie theater down..");
        pop.off();
        light.on();
        screen.up();
        project.off();
        amp.off();
       dvd.off();
    }
}

3.现在来简单测试一下吧

public class FacadePattern {
    public static void main(String args[]){
        Amplifier amp = new Amplifier();
        Tuner tuner = new Tuner() ;
        DVDPlayer dvd = new DVDPlayer();
        CDPlayer cd = new CDPlayer(); 
        Projector project = new Projector();;
        TheaterLights light = new TheaterLights();
        Screen screen = new Screen();
        PopcornPopper pop = new PopcornPopper();                   
        HomeTheaterFacade facade = new HomeTheaterFacade(amp,tuner,dvd,cd,project,light,screen,pop);
        facade.watchMovie("movie");
        facade.endMovie("movie");
    }
}

4.运行结果
get ready to watch a movie..
正在打开爆米花机。。
正在蹦爆米花。。
正在调暗灯光。。
正在放下屏幕。。
正在打开投影仪。。
正在设置宽屏模式。。
欢迎使用功放类。。
正在安放DVD、。。
设置环绕立体声。。
正在设置音量。。
正在打开DVD。。
正在播放DVD。。
shutting movie theater down..
正在关闭爆米花机。。
正在打开灯光。。
正在生起屏幕。。
正在关闭投影仪。。
已经关闭功放。。
正在关闭DVD。。


*我的理解是这样的:
就是由一堆类,每个类对象都要执行一些方法,如果直接new这些类创建对象去调方法会与这些类产生耦合,这时单独再写一个外观类,构造初始化时拿到这些类对象,在一个方法里去调这些类对象的方法,这样对客户来说只和一个类打交道,与子系统的一堆类解耦了。*


这里写图片描述


适配器模式 PK 外观模式
1.当需要使用一个现有的类,而其接口并不符合你的需要时,就使用适配器。
2.当需要简化并统一一个很大的接口或者一群复杂的接口时,使用外观。
1.适配器改变接口以符合客户的希望
2.外观将一个客户从复杂的子系统中解耦。
1.实现一个适配器可能需要一番功夫,也可能不费工夫,视目标接口的大小与复杂度而定。
2.实现一个外观,需要将子系统组合进外观中,然后将工作委托给子系统执行。
1.适配器模式有两种形式,对象适配器和类适配器。类适配器需要用到多重继承。
2.你可以为一个子系统实现一个以上的外观。
1.适配器将一个对象包装起来以改变其接口;装饰器将一个对象包装起来以增加新的行为和责任,而外观将一群对象包装起来以简化其接口。

猜你喜欢

转载自blog.csdn.net/FightingITPanda/article/details/81251669