设计模式(六)
组件构建过程中,某些接口之间的依赖常常会带来很多问题,甚至根本无法实现。采用添加一层间接稳定接口,来隔离本来互相紧密关联的接口是一种常见的解决方案
1.门面(Facade):门面类知道哪些子系统负责处理哪些请求,将客户端的请求代理给适当的子系统对象
2.子系统(Subsystem):实现子系统的功能。子系统并不意识到门面,它们接受请求并处理,通常是由多个类组成的复杂系统
3.客户端(Client):使用门面来与子系统进行交互
eg:
// 子系统类
class Subsystem1 {
public:
void operation1() {
// ...
}
};
class Subsystem2 {
public:
void operation2() {
// ...
}
};
class Subsystem3 {
public:
void operation3() {
// ...
}
};
// 门面类
class Facade {
private:
Subsystem1* subsystem1;
Subsystem2* subsystem2;
Subsystem3* subsystem3;
public:
Facade() {
subsystem1 = new Subsystem1();
subsystem2 = new Subsystem2();
subsystem3 = new Subsystem3();
}
void operation() {
subsystem1->operation1();
subsystem2->operation2();
subsystem3->operation3();
}
~Facade() {
delete subsystem1;
delete subsystem2;
delete subsystem3;
}
};
// 客户端代码
int main() {
Facade* facade = new Facade();
facade->operation();
delete facade;
return 0;
}
代理模式
允许我们为其他对象提供一种代理以控制对这个对象的访问。代理模式的关键是提供一个替身或占位符,以控制对原始对象的访问
不改变原始对象代码的情况下,通过引入代理对象来间接访问原始对象,以添加额外的功能,如访问控制、日志记录、缓存等
1.抽象主题(Subject):定义了RealSubject和Proxy的共用接口,这样就可以使用代理来代替真实对象。
2.真实主题(RealSubject):定义了代理所代表的真实对象,代理会控制对它的访问。
3.代理(Proxy):保存一个引用使得代理可以访问真实对象,并提供一个与真实主题相同的接口。代理可以附加一些额外的功能,如权限验证、延迟加载等
// 抽象主题
class Image {
public:
virtual void display() = 0;
};
// 真实主题
class RealImage : public Image {
private:
string filename;
public:
RealImage(string filename) {
this->filename = filename;
loadFromDisk();
}
void display() override {
cout << "Displaying " << filename << endl;
}
private:
void loadFromDisk() {
cout << "Loading " << filename << endl;
}
};
// 代理
class ProxyImage : public Image {
private:
RealImage* realImage;
string filename;
public:
ProxyImage(string filename) {
this->filename = filename;
}
~ProxyImage() {
delete realImage;
}
void display() override {
if (realImage == nullptr) {
realImage = new RealImage(filename);
}
realImage->display();
}
};
// 客户端代码
int main() {
Image* image = new ProxyImage("test_image.jpg");
// 图像将在第一次显示时加载
image->display();
cout << "---------------------" << endl;
// 图像不会再次从磁盘加载
image->display();
delete image;
return 0;
}
适配器模式
将一个类得接口转换成客户希望得另一个接口,Adapter模式使得原本由于接口不兼容而不能一起工作得那些类可以一起工作
1.目标接口(Target):定义客户端使用的接口,客户端期望与这个接口协同工作。
2.被适配者(Adaptee):一个已经存在的类或对象,其接口与目标接口不兼容。
3.适配器(Adapter):一个中介类,通过继承或组合的方式实现目标接口,并将目标接口的调用转化为被适配者接口的调用
eg:
// 目标接口
class Target {
public:
virtual void request() = 0;
};
// 被适配者
class Adaptee {
public:
void specificRequest() {
// 实现特定的功能
}
};
// 适配器
class Adapter : public Target {
private:
Adaptee* adaptee;
public:
Adapter(Adaptee* adaptee) {
this->adaptee = adaptee;
}
void request() override {
// 调用被适配者的方法以实现目标接口
adaptee->specificRequest();
}
};
// 客户端代码
int main() {
Adaptee* adaptee = new Adaptee();
Target* adapter = new Adapter(adaptee);
// 客户端通过目标接口与适配器交互
adapter->request();
delete adaptee;
delete adapter;
return 0;
}
将目标接口与被适配者解耦,使得两者可以独立变化,通过引入一个适配器类,可以在不修改现有代码的基础上增加新的接口功能
中介模式
将多个对象间复杂得关系解耦,Mediator模式将多个对象间得控制逻辑进行集中管理,变多个对象互相关联 为多个对象和一个中介者关联,简化了系统得维护,抵御了可能得变化
将原理相互依赖得对象,现在使其分离,然后让所有对象和一个中间对象相互依赖
// 中介者接口
class Mediator {
public:
virtual void send(std::string message, Colleague* sender) = 0;
};
// 同事接口
class Colleague {
protected:
Mediator* mediator;
public:
Colleague(Mediator* mediator) {
this->mediator = mediator;
}
};
// 具体的同事类
class ConcreteColleague1 : public Colleague {
public:
ConcreteColleague1(Mediator* mediator) : Colleague(mediator) {}
void send(std::string message) {
mediator->send(message, this);
}
void notify(std::string message) {
std::cout << "Colleague1 gets message: " << message << std::endl;
}
};
class ConcreteColleague2 : public Colleague {
public:
ConcreteColleague2(Mediator* mediator) : Colleague(mediator) {}
void send(std::string message) {
mediator->send(message, this);
}
void notify(std::string message) {
std::cout << "Colleague2 gets message: " << message << std::endl;
}
};
// 具体的中介者类
class ConcreteMediator : public Mediator {
private:
ConcreteColleague1* colleague1;
ConcreteColleague2* colleague2;
public:
ConcreteMediator() : colleague1(nullptr), colleague2(nullptr) {}
void setColleague1(ConcreteColleague1* colleague) {
this->colleague1 = colleague;
}
void setColleague2(ConcreteColleague2* colleague) {
this->colleague2 = colleague;
}
void send(std::string message, Colleague* sender) override {
if (sender == colleague1) {
colleague2->notify(message);
} else {
colleague1->notify(message);
}
}
};
// 客户端代码
int main() {
ConcreteMediator mediator;
ConcreteColleague1 colleague1(&mediator);
ConcreteColleague2 colleague2(&mediator);
mediator.setColleague1(&colleague1);
mediator.setColleague2(&colleague2);
colleague1.send("Hello from Colleague1");
colleague2.send("Hello from Colleague2");
return 0;
}
- 集中控制:所有消息传递的逻辑都集中在
ConcreteMediator
类中,这使得管理和修改消息传递规则变得更加容易 - 简化对象通信:同事对象不需要知道其他同事对象的存在或如何与它们通信。它们只需要知道如何与中介者通信