目录
1、外观模式(Facade Pattern)含义
2、外观模式的UML图学习
3、外观模式的应用场景
4、外观模式的优缺点
5、C++实现外观模式的简单实例
1、外观模式(Facade Pattern)含义
外观模式(Facade Pattern),为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
(1)外观模式隐藏了子系统的复杂性,为客户端提供了一个简单的接口,使得客户端更容易使用子系统。
(2)外观模式的核心思想是通过创建一个外观类(也称为门面类),将客户端与子系统解耦,客户端只需要通过外观类来与子系统进行交互,而不需要直接调用子系统的接口。
2、外观模式的UML图学习
在外观模式中,有以下几个关键角色:
(1)外观(Facade):外观类是外观模式的核心,它提供了一个简单的接口,用于访问子系统中的一组接口。外观类封装了对子系统的调用,隐藏了子系统的复杂性,为客户端提供了一个简单的接口。
(2)子系统(Subsystem):子系统是实现具体功能的一组类或模块。每个子系统都有自己的一组接口和实现逻辑。子系统可以是一个或多个类的集合。
(3)客户端(Client):客户端通过外观类来与子系统进行交互。客户端不需要直接调用子系统的接口,而是通过外观类提供的简单接口来完成操作。
在外观模式中,外观类充当了客户端与子系统之间的中介,它将客户端的请求转发给子系统,并将子系统的结果返回给客户端。这样,客户端只需要与外观类进行交互,而无需了解子系统的具体实现细节。
外观模式的目的是简化客户端与子系统之间的交互,降低耦合度,提高系统的可维护性和可扩展性。
3、外观模式的应用场景
(1)当需要简化复杂子系统的接口并提供一个统一的接口时。
(2)当需要将客户端与子系统解耦,以降低客户端与子系统之间的依赖性时。
(3)当需要对子系统进行封装,隐藏其复杂性,提高系统的易用性和可维护性时。
4、外观模式的优缺点
(1)优点:
1)简化接口:外观模式提供了一个简单的接口,隐藏了子系统的复杂性。客户端只需要与外观类进行交互,无需了解子系统的具体实现细节,从而简化了客户端的调用过程。
2)解耦子系统和客户端:外观模式将客户端与子系统之间的依赖关系解耦,使得它们可以独立演化。当子系统发生变化时,只需要调整外观类即可,而不会影响到客户端。
3)提高可维护性:外观模式将复杂的子系统封装在一个外观类中,使得系统结构更加清晰,易于理解和维护。对于客户端来说,只需要关注外观类的接口,而不需要关心子系统的具体实现。
4)提高代码复用性:外观模式可以将一些常用的操作封装在外观类中,供多个客户端共享使用,从而提高了代码的复用性。
(2)缺点:
1)不符合开闭原则:当需要新增或修改子系统的功能时,可能需要修改外观类的代码。这违反了开闭原则,可能会导致外观类的修改引起其他客户端的不稳定。
2)可能引入性能问题:外观模式可能会引入一层间接调用,导致系统性能下降。因此,在设计时需要权衡系统的性能和代码结构的清晰度。
3)可能增加系统复杂性:如果一个系统本身就很简单,使用外观模式可能会增加不必要的复杂性,使得代码变得冗余。
总体来说,外观模式是一种有用的设计模式,可以提供简化的接口,解耦子系统和客户端,并提高系统的可维护性和可扩展性。但在使用时需要注意遵循设计原则,权衡好代码的灵活性、性能和复杂性。
5、C++实现外观模式的简单实例
#include <iostream>
// 子系统A
class SubsystemA
{
public:
void operationA()
{
std::cout << "Subsystem A operation" << std::endl;
}
};
// 子系统B
class SubsystemB
{
public:
void operationB()
{
std::cout << "Subsystem B operation" << std::endl;
}
};
// 外观类
class Facade
{
private:
SubsystemA subsystemA;
SubsystemB subsystemB;
public:
void operation()
{
subsystemA.operationA();
subsystemB.operationB();
}
};
int main()
{
// 创建外观对象
Facade facade;
// 调用外观对象的操作方法
facade.operation();
return 0;
}
在上述示例中,我们定义了两个子系统类 SubsystemA 和 SubsystemB,分别具有自己的操作方法 operationA 和 operationB。
然后,我们创建了一个外观类 Facade,该类持有 SubsystemA 和 SubsystemB 的实例,并提供了一个操作方法 operation,该方法内部调用了子系统的操作方法。
在 main 函数中,我们创建了一个外观对象 facade,并通过调用 facade.operation() 来间接访问子系统的功能。
运行以上代码,输出将会是:
Subsystem A operation
Subsystem B operation
可以看到,通过外观模式,我们可以通过简单的接口来访问复杂的子系统功能,而无需直接与子系统进行交互。