设计模式---外观模式

6 阅读2分钟

定义

外观模式(Facade Pattern)是一种结构型设计模式,它为子系统中的一组接口提供了一个统一的高层接口,使得子系统更加容易使用。外观模式通过定义一个高层接口来隐藏子系统的复杂性,从而简化客户端的使用。

结构

  • Facade(外观类) :提供一个统一的接口,用来访问子系统中的一群接口。

  • Subsystem classes(子系统类) :实现子系统的功能,处理Facade对象指派的任务。子系统不知道Facade的存在,对子系统而言,Facade只是另一个客户端。

优点

  • 简化使用:通过引入外观类,可以简化客户端对子系统的使用。

  • 松散耦合:外观模式降低了客户端与子系统之间的耦合,使得子系统的变化不会影响到客户端。

  • 更好的划分:通过外观类,子系统内部可以更好地划分和管理,客户端只需要与外观类交互。

代码示例

#include <iostream>

// 音响类
class Amplifier 
{
public:
    void on() 
    {
        std::cout << "Amplifier on" << std::endl;
    }

    void setVolume(int volume) 
    {
        std::cout << "Setting volume to " << volume << std::endl;
    }

    void off() 
    {
        std::cout << "Amplifier off" << std::endl;
    }
};


// DVD播放器类
class DVDPlayer
{
public:
    void on() 
    {
        std::cout << "DVD Player on" << std::endl;
    }

    void play(const std::string& movie) 
    {
        std::cout << "Playing \"" << movie << "\"" << std::endl;
    }

    void stop() 
    {
        std::cout << "Stopping DVD" << std::endl;
    }

    void eject() 
    {
        std::cout << "Ejecting DVD" << std::endl;
    }

    void off() 
    {
        std::cout << "DVD Player off" << std::endl;
    }
};



// 投影仪类
class Projector 
{
public:
    void on() 
    {
        std::cout << "Projector on" << std::endl;
    }

    void wideScreenMode() 
    {
        std::cout << "Projector in widescreen mode" << std::endl;
    }

    void off() 
    {
        std::cout << "Projector off" << std::endl;
    }
};


// 外观类:家庭影院
class HomeTheaterFacade 
{
private:
    Amplifier* amp;
    DVDPlayer* dvd;
    Projector* projector;

public:
    HomeTheaterFacade(Amplifier* amp, DVDPlayer* dvd, Projector* projector)
        : amp(amp), dvd(dvd), projector(projector) {}

    // 观看电影
    void watchMovie(const std::string& movie)
    {
        std::cout << "Get ready to watch a movie..." << std::endl;
        projector->on();
        projector->wideScreenMode();
        amp->on();
        amp->setVolume(5);
        dvd->on();
        dvd->play(movie);
    }

    // 关闭电影
    void endMovie()
    {
        std::cout << "Shutting movie theater down..." << std::endl;
        dvd->stop();
        dvd->eject();
        dvd->off();
        amp->off();
        projector->off();
    }
};



int main() 
{
    Amplifier amp;
    DVDPlayer dvd;
    Projector projector;

    HomeTheaterFacade homeTheater(&amp, &dvd, &projector);

    homeTheater.watchMovie("Inception");
    homeTheater.endMovie();

    system("pause");
    return 0;
}
  • AmplifierDVDPlayerProjector 是子系统类,分别表示音响、DVD 播放器和投影仪。
  • HomeTheaterFacade 是外观类,它封装了子系统类的复杂操作,对外提供了 watchMovieendMovie 方法,简化了客户端的使用。
  • 客户端代码通过 HomeTheaterFacade 类来控制家庭影院系统,而不需要直接与各个子系统类交互。

应用场景

  • 简化复杂系统:当一个系统非常复杂,使用外观模式可以提供一个简单的接口来使用系统。

  • 层次化结构:当一个系统由多个层次组成时,使用外观模式可以定义每一层的接口,简化层与层之间的依赖关系。

  • 遗留系统:在对遗留系统进行封装时,可以使用外观模式提供一个新的接口,简化遗留系统的使用。