欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 国际 > 11结构型设计模式——外观模式

11结构型设计模式——外观模式

2025/2/5 14:05:53 来源:https://blog.csdn.net/qq_55610255/article/details/141298459  浏览:    关键词:11结构型设计模式——外观模式

一、外观模式简介

外观模式(Facade Pattern)是一种结构型设计模式,它提供了一个统一的接口来访问子系统中的一组接口,使得子系统的使用更加简单和方便。通过外观模式,可以将复杂的子系统封装在一个外观类(Facade)中,从而减少代码的耦合度,提高系统的可维护性和易用性。

外观模式的结构图

  1. 外观类(Facade):提供一个高层接口,简化了对子系统的操作。
  2. 子系统类(Subsystem Classes):实现具体的业务功能,通常这些类之间有复杂的依赖关系。

外观模式的核心概念

  1. 简化接口:外观模式将复杂的子系统接口封装在一个简单的外观类中,用户只需要与这个外观类交互,而不必直接使用复杂的子系统接口。

  2. 降低耦合度:通过引入外观类,外部代码与复杂的子系统解耦,从而减少系统间的依赖关系。

  3. 提高可维护性:因为外观模式提供了简化的接口,所以修改子系统的实现不会直接影响到使用外观类的代码,系统的维护和扩展变得更加方便。

二、外观模式的应用场景

1. 简化复杂系统的接口

当一个系统由多个子系统组成,每个子系统有自己的接口和功能时,外观模式可以提供一个统一的接口,简化系统的使用。例如:

  • 家庭影院系统:如前面所述,通过外观模式,可以将电视、音响、DVD播放器等设备的操作封装在一个简单的接口中,使得用户可以更轻松地控制整个家庭影院系统。

  • 图形库:图形库可能提供复杂的图形绘制功能,通过外观模式,可以将这些功能封装成一个简单的接口,方便应用程序的调用。

2. 减少系统间的耦合

外观模式通过引入外观类,使得系统的不同部分之间的耦合度降低。这样,即使子系统发生变化,外部代码也不会受到影响。例如:

  • 第三方库的集成:当集成第三方库时,外观模式可以封装这些库的复杂接口,使得应用程序只需与外观类交互,而不必处理第三方库的细节。

3. 提升代码的可维护性

外观模式有助于将复杂的子系统封装在一个单一的外观类中,从而提高代码的可维护性和可读性。例如:

  • 配置管理:当系统需要处理多个配置模块时,可以使用外观模式将这些模块封装在一个统一的配置管理类中,简化配置的管理和使用。

4. 构建高层接口

在构建一个大型应用程序时,外观模式可以用来提供高层接口,使得不同层次的功能可以更清晰地进行组织和调用。例如:

  • Web应用程序:在Web应用程序中,外观模式可以用来封装不同的服务,如用户管理、订单处理等,为控制器提供简洁的接口。

5. 提升系统的扩展性

通过引入外观类,可以在不修改现有代码的情况下扩展系统。例如:

  • 插件系统:在插件架构中,外观模式可以用来提供统一的插件接口,使得在添加或修改插件时,不必更改核心系统的实现。

6. 简化测试

在进行单元测试时,外观模式可以帮助创建一个简单的测试接口,从而简化测试的编写和维护。例如:

  • 测试复杂的业务流程:使用外观模式将复杂的业务流程封装在一个测试接口中,可以更方便地测试整个流程的正确性。

7. 过渡旧系统

在将旧系统迁移到新系统时,可以使用外观模式提供一个兼容的接口,使得新系统可以与旧系统进行交互,而不必修改旧系统的实现。例如:

  • 迁移到新的数据存储解决方案:在迁移数据库时,外观模式可以用来封装旧数据库的接口,使得应用程序可以继续正常工作,直到新数据库的迁移完成。

三、外观模式的设计方法

假设我们有一个复杂的家庭影院系统,包括电视、音响和DVD播放器、APP、CCTV。我们希望通过一个简单的接口来控制这个系统,而不必直接操作每个子系统。

facade.cpp

#include <iostream>
#include <string>// 子系统
class TV {
public:void turnOn() { std::cout << "TV is now ON\n"; }void turnOff() { std::cout << "TV is now OFF\n"; }
};class SoundSystem {
public:void turnOn() { std::cout << "Dolby Atmos Sound System is now ON\n"; }void turnOff() { std::cout << "Sound System is now OFF\n"; }
};class DVDPlayer {
public:void turnOn() { std::cout << "DVD Player is now ON\n"; }void turnOff() { std::cout << "DVD Player is now OFF\n"; }
};class TencentAPP {
public:void turnOn() { std::cout << "Tencent APP is now ON\n"; }void turnOff() { std::cout << "Tencent APP is now OFF\n"; }
};class CCTV {
public:void turnOn() { std::cout << "CCTV is now ON\n"; }void turnOff() { std::cout << "CCTV is now OFF\n"; }
};// 家庭影音
class HomeTheaterFacade {
public:HomeTheaterFacade(TV* tv, SoundSystem* soundSystem, TencentAPP* tencentAPP, CCTV* cctv): tv_(tv), soundSystem_(soundSystem), tencentAPP_(tencentAPP), cctv_(cctv) {}void watchMovie() {std::cout << "Get ready to watch a movie...\n";tv_->turnOn();soundSystem_->turnOn();tencentAPP_->turnOn();cctv_->turnOn();}void endMovie() {std::cout << "Shutting down movie setup...\n";cctv_->turnOff();tencentAPP_->turnOff();soundSystem_->turnOff();tv_->turnOff();}private:TV* tv_;SoundSystem* soundSystem_;TencentAPP* tencentAPP_;CCTV* cctv_;
};// 电影院
class CinemaFacade {
public:CinemaFacade(TV* tv, SoundSystem* soundSystem, DVDPlayer* dvdPlayer): tv_(tv), soundSystem_(soundSystem), dvdPlayer_(dvdPlayer) {}void watchMovie() {std::cout << "Get ready to watch a movie...\n";tv_->turnOn();soundSystem_->turnOn();dvdPlayer_->turnOn();}void endMovie() {std::cout << "Shutting down movie setup...\n";dvdPlayer_->turnOff();soundSystem_->turnOff();tv_->turnOff();}private:TV* tv_;SoundSystem* soundSystem_;DVDPlayer* dvdPlayer_;
};// 使用外观类
void doWorking(const int type) {if(type == 1) {TV tv;SoundSystem soundSystem;TencentAPP tencentAPP;CCTV cctv;HomeTheaterFacade homeTheater(&tv, &soundSystem, &tencentAPP, &cctv);homeTheater.watchMovie();  // 开始看电影homeTheater.endMovie();    // 结束电影}else if(type == 2) {TV tv;SoundSystem soundSystem;DVDPlayer dvdPlayer;CinemaFacade cinema(&tv, &soundSystem, &dvdPlayer);cinema.watchMovie();  // 开始看电影cinema.endMovie();    // 结束电影}
}int main() {int type;std::cout << "Please select the Viewing mode: 家庭影音(1) or 电影院(2): ";std::cin >> type;doWorking(type);return 0;
}

运行效果

四、总结

外观模式的应用可以使看起来复杂的外观简化,使得系统看起来更加直观和方便。

外观模式的缺点

  1. 可能引入过度封装:外观类可能会过度封装,导致子系统的某些功能无法被直接访问。
  2. 不适用于所有场景:对于需要高度定制的场景,外观模式可能不适用,因为它提供的是统一的接口,可能无法满足所有特定需求。

外观模式的优点

  1. 简化代码:通过提供统一的接口,简化了复杂系统的使用。
  2. 降低耦合:外部代码不需要直接依赖于复杂的子系统。
  3. 提高灵活性:修改或扩展子系统的实现不会影响到使用外观类的代码。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com