概述
外观模式是一种使用频率非常高的结构型设计模式,它通过引入一个外观角色来简化客户端与子系统之间的交互,为复杂的子系统调用提供一个统一的入口,降低子系统与客户端的耦合度,且客户端调用非常方便。
定义:外观模式(Facade Pattern):外部与一个子系统的通信必须通过一个统一的外观对象进行,为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。外观模式又称为门面模式,它是一种对象结构型模式。
UML图:
角色介绍:
Facade:外观角色,客户端直接调用他的方法,他清楚各个子系统的功能责任,能够调用各个子系统的方法。
System:子系统角色,可以是一个类或者类的集合,完成某项功能,能够被客户端或者外观类直接调用,他并不知道外观类的存在,对于他来说,外观类也只是个客户端。
代码体现:
#include<string>
#include<iostream>
using namespace std;
class SystemA
{
public:
void operationA()
{
cout << "A" << endl;
}
};
class SystemB
{
public:
void operationB()
{
cout << "B" << endl;
}
};
class SystemC
{
public:
void operationC()
{
cout << "C" << endl;
}
};
//外观类
class Facade
{
public:
Facade()
{
systemA = new SystemA();
systemB = new SystemB();
systemC = new SystemC();
};
~Facade()
{
delete systemA;
delete systemB;
delete systemC;
};
void WrapOperation()
{
systemA->operationA();
systemB->operationB();
systemC->operationC();
};
private:
SystemA * systemA;
SystemB * systemB;
SystemC * systemC;
};
//使用
int main()
{
Facade fac;
fac.WrapOperation();
system("pause");
return 0;
}
相比之前的设计模式,外观模式很好理解,只有简单的调用关系,比较常用,但是如果增加了子系统,那就要对外观类进行修改,不符合开闭原则,所以,可以设计一个抽象外观类,具体的抽象类继承自该抽象外观,增加子系统只需要增加具体外观类即可。
优缺点及适用场景:
优点:
1. 它对客户端屏蔽了子系统组件,减少了客户端所需处理的对象数目,并使得子系统使用起来更加容易。通过引入外观模式,客户端代码将变得很简单,与之关联的对象也很少。
2. 它实现了子系统与客户端之间的松耦合关系,这使得子系统的变化不会影响到调用它的客户端,只需要调整外观类即可。
3. 一个子系统的修改对其他子系统没有任何影响,而且子系统内部变化也不会影响到外观对象。
缺点:
1. 不能很好地限制客户端直接使用子系统类,如果对客户端访问子系统类做太多的限制则减少了可变性和灵活 性。
2. 如果设计不当,增加新的子系统可能需要修改外观类的源代码,违背了开闭原则。
适用场景:
1.当要为一个复杂子系统提供一个简单接口时可以使用外观模式。该接口可以满足大多数用户的需求,而且用户也可以越过外观类直接访问子系统。
2.客户程序与多个子系统之间存在很大的依赖性。引入外观类将子系统与客户以及其他子系统解耦,可以提高子系统的独立性和可移植性。
3.在层次化结构中,可以使用外观模式定义系统中每一层的入口,层与层之间不直接产生联系,而通过外观类建立联系,降低层之间的耦合度