设计模式之外观模式

来源:互联网 发布:mac系统iso镜像下载 编辑:程序博客网 时间:2024/06/05 20:24

一、模式动机

  当需要简化并统一一个很大的接口或者一群复杂的接口时,使用外观模式。外观模式(Facade-Pattern),之所以这么称呼,是因为它将一个或数个类的复杂一切都隐藏在背后,只显露出一个干净美好的外观。

二、模式定义

  外观模式(Facade Pattern):提供了一个统一的接口,用来访问子系统中的一群接口。外观定义一个高层接口,让子系统更容易使用。

这里写图片描述

三、模式示例

  你组装了一套杀手级的家庭影院系统,内含DVD播放器、投影仪、自动屏幕、环绕立体声,甚至还有爆米花。如下图所示:

这里写图片描述

  但是观赏电影需要操作很多步,打开爆米花机,开始爆米花,将灯光调暗,放下屏幕,将投影机的输入切换到DVD…打开DVD播放器,开始播放DVD。现在用外观模式,一键搞定。

C++代码实现

#include <iostream>#include <string>using namespace std;class TheaterLights{public:    TheaterLights();    ~TheaterLights();    void on(){ cout << "Theater Lights On" << endl; }    void off(){ cout << "Theater Lights Off" << endl; }    void dim(int val){ cout << "Theater Lights Dim" << endl; }private:};TheaterLights::TheaterLights(){}TheaterLights::~TheaterLights(){}class PopcomPopper{public:    PopcomPopper();    ~PopcomPopper();    void on(){ cout << "PopcomPopper On" << endl; }    void off(){ cout << "PopcomPopper Off" << endl; }    void pop(){ cout << "PopcomPopper Pop" << endl; }private:};PopcomPopper::PopcomPopper(){}PopcomPopper::~PopcomPopper(){}class Screen{public:    Screen();    ~Screen();    void down(){ cout << "Screen Down" << endl; }    void up(){ cout << "Screen Up" << endl; }private:};Screen::Screen(){}Screen::~Screen(){}class Amplifier;class Tuner{public:    Tuner();    ~Tuner();    void on(){ cout << "Tuner On" << endl; }    void off(){ cout << "Tuner Off" << endl; }    void setAmplifier(Amplifier* am) { amplifier = am; }private:    Amplifier* amplifier;};Tuner::Tuner(){}Tuner::~Tuner(){}class CdPlayer{public:    CdPlayer();    ~CdPlayer();    void on(){ cout << "CdPlayer On" << endl; }    void off(){ cout << "CdPlayer Off" << endl; }    void setAmplifier(Amplifier* am) { amplifier = am; }private:    Amplifier* amplifier;};CdPlayer::CdPlayer(){}CdPlayer::~CdPlayer(){}class DvdPlayer{public:    DvdPlayer();    ~DvdPlayer();    void on(){ cout << "DvdPlayer On" << endl; }    void off(){ cout << "DvdPlayer Off" << endl; }    void setAmplifier(Amplifier* am) { amplifier = am; }private:    Amplifier* amplifier;};DvdPlayer::DvdPlayer(){}DvdPlayer::~DvdPlayer(){}class Projector{public:    Projector();    ~Projector();    void on(){ cout << "DvdPlayer On" << endl; }    void off(){ cout << "DvdPlayer Off" << endl; }    void setDvdPlayer(DvdPlayer* player) { dvdPlayer = player; }private:    DvdPlayer* dvdPlayer;};Projector::Projector(){}Projector::~Projector(){}class Amplifier{public:    Amplifier();    ~Amplifier();    void on(){ cout << "Amplifier On" << endl; }    void off(){ cout << "Amplifier Off" << endl; }    void setDvdPlayer(DvdPlayer* player) { dvdPlayer = player; }    void setStereoSound(){ cout << "Amplifier Set StereoSound" << endl; }    void setVolume(int volume){ cout << "Amplifier Set Volume" << endl; }private:    DvdPlayer* dvdPlayer;};Amplifier::Amplifier(){}Amplifier::~Amplifier(){}class HomeTheaterFacade{public:    HomeTheaterFacade(Amplifier* amp, Tuner* tuner, DvdPlayer* dvd, CdPlayer* cd, Projector* projector, TheaterLights* lights, PopcomPopper* poper);    ~HomeTheaterFacade();    void watchMovie(string movie);private:    Amplifier* amp;    Tuner* tuner;    DvdPlayer* dvd;    CdPlayer* cd;    Projector* projector;    TheaterLights* lights;    Screen* screen;    PopcomPopper* poper;};HomeTheaterFacade::HomeTheaterFacade(Amplifier* amp, Tuner* tuner, DvdPlayer* dvd, CdPlayer* cd, Projector* projector, TheaterLights* lights, PopcomPopper* poper)    :amp(amp),    tuner(tuner),    dvd(dvd),    cd(cd),    projector(projector),    lights(lights),    poper(poper){}HomeTheaterFacade::~HomeTheaterFacade(){}void HomeTheaterFacade::watchMovie(string movie) {     cout << "Get ready to watch " + movie << endl;     poper->on();    poper->pop();    lights->dim(10);    screen->down();    projector->on();    amp->on();    amp->setStereoSound();    amp->setVolume(5);    dvd->on();}int _tmain(int argc, _TCHAR* argv[]){    TheaterLights* lights = new TheaterLights;    PopcomPopper* poper = new PopcomPopper;    Screen* screen = new Screen;    Tuner* tuner = new Tuner;    CdPlayer* cd = new CdPlayer;    DvdPlayer* dvd = new DvdPlayer;    Projector* projector = new Projector;    Amplifier* amp = new Amplifier;    projector->setDvdPlayer(dvd);    dvd->setAmplifier(amp);    cd->setAmplifier(amp);    tuner->setAmplifier(amp);    amp->setDvdPlayer(dvd);    HomeTheaterFacade  homeTheater(amp, tuner, dvd, cd, projector, lights, poper);    homeTheater.watchMovie("1942");    system("pause");    return 0;}

运行结果:

这里写图片描述

四、分析总结

   外观模式将客户从一个复杂的子系统中解耦。实现一个外观,需要将子系统组合进外观中,然后将工作委托给子系统执行。

优点

  • 实现了子系统与客户之间的松耦合关系,这使得子系统的组件变化不会影响到调用它的客户类,只需要调整外观类即可
  • 只是提供了一个访问子系统的统一入口,并不影响用户直接使用子系统类

缺点

  • 在不引入抽象外观类的情况下,增加新的子系统可能需要修改外观类或客户端的源代码,违背了“开放-关闭原则”。
原创粉丝点击