介绍
外观模式中外部与一个子系统的通信通过一个统一的外观角色进行,为子系统中的一组接口提供一个一致的入口。外观模式定义了一个高层接口,这个接口使得子系统更加容易使用。外观模式又称为门面模式,它是一种对象结构型模式。
实现
myclass.h
//
// Created by yuwp on 2024/1/12.
//
#ifndef DESIGNPATTERNS_MYCLASS_H
#define DESIGNPATTERNS_MYCLASS_H
#include <iostream>
#include <vector>
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()" << std::endl;
}
Facade::Facade() {
m_subA = new SubSystemA;
m_subB = new SubSystemB;
}
Facade::~Facade() {
if (m_subA) {
delete m_subA;
}
if (m_subB) {
delete m_subB;
}
}
void Facade::method() {
if (m_subA) {
m_subA->methodA();
}
if (m_subB) {
m_subB->methodB();
}
}
main.cpp
#include <iostream>
#include <mutex>
#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 <iostream>
#include <vector>
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 << "------- 开始备份 ---------" << std::endl;
if (m_addrBook) {
m_addrBook->moveTo(path);
}
if (m_msgManager) {
m_msgManager->moveTo(path);
}
std::cout << "------- 备份完成 ---------" << std::endl;
}
main.cpp
#include <iostream>
#include <mutex>
#include "myclass.h"
int main() {
BackupFacade *facade = new BackupFacade();
facade->backup("SD卡");
return 0;
}