介绍
外观模式中外部与一个子系统的通信通过一个统一的外观角色进行,为子系统中的一组接口提供一个一致的入口。外观模式定义了一个高层接口,这个接口使得子系统更加容易使用。外观模式又称为门面模式,它是一种对象结构型模式。
实现
myclass.h
//// Created by yuwp on 2024/1/12.//#ifndef DESIGNPATTERNS_MYCLASS_H#define DESIGNPATTERNS_MYCLASS_H#include #include class SubSystemA {public:void methodA();};class SubSystemB {public:void methodB();};class Facade {public:Facade();~Facade();void method();private:SubSystemA *m_subA;SubSystemB *m_subB;};#endif //DESIGNPATTERNS_MYCLASS_H
myclass.cpp
//// Created by yuwp on 2024/1/12.//#include "myclass.h"void SubSystemA::methodA() {std::cout << "SubSystemA::methodA()" << std::endl;}void SubSystemB::methodB() {std::cout << "SubSystemB::methodB()" <methodA();}if (m_subB) {m_subB->methodB();}}
main.cpp
#include #include #include "myclass.h"int main() {Facade *facade = new Facade();facade->method();return 0;}
总结
优点
1.对客户端屏蔽了子系统组件,减少了客户端所需处理的对象数目并使得子系统使用起来更加容易。通过引入外观模式,客户端代码将变得很简单,与之关联的对象也很少。
2.实现了子系统与客户端之间的松耦合关系,这使得子系统的变化不会影响到调用它的客户端,只需要调整外观类即可。
3.一个子系统的修改对其他子系统没有任何影响,而且子系统内部变化也不会影响到外观对象。
4.只是提供了一个访问子系统的统一入口,并不影响客户端直接使用子系统类。
缺点
1.不能很好地限制客户端直接使用子系统类,如果对客户端访问子系统类做太多的限制则减少了可变性和灵活性。
2.如果设计不当,增加新的子系统可能需要修改外观类的源代码,这违背了开闭原则。
练习
myclass.h
//// Created by yuwp on 2024/1/12.//#ifndef DESIGNPATTERNS_MYCLASS_H#define DESIGNPATTERNS_MYCLASS_H#include #include class AddressBook {public:void moveTo(const std::string &path);};class MsgManager {public:void moveTo(const std::string &path);};class BackupFacade {public:BackupFacade();~BackupFacade();void backup(const std::string &path);private:AddressBook *m_addrBook;MsgManager *m_msgManager;};#endif //DESIGNPATTERNS_MYCLASS_H
myclass.cpp
//// Created by yuwp on 2024/1/12.//#include "myclass.h"void AddressBook::moveTo(const std::string &path) {std::cout << "将通讯录移动到" << path << std::endl;}void MsgManager::moveTo(const std::string &path) {std::cout << "将短信移动到" << path << std::endl;}BackupFacade::BackupFacade() {m_addrBook = new AddressBook;m_msgManager = new MsgManager;}BackupFacade::~BackupFacade() {if (m_addrBook) {delete m_addrBook;}if (m_msgManager) {delete m_msgManager;}}void BackupFacade::backup(const std::string &path) {std::cout << "------- 开始备份 ---------" <moveTo(path);}if (m_msgManager) {m_msgManager->moveTo(path);}std::cout << "------- 备份完成 ---------" << std::endl;}
main.cpp
#include #include #include "myclass.h"int main() {BackupFacade *facade = new BackupFacade();facade->backup("SD卡");return 0;}