模式:Facade模式,也称为外观模式。
模式描述:
在我们使用一个复杂系统的一些功能时,可以通过外观模式对这些功能进行包装,使得应用程序只能看到该接口,而不会看到该系统的实现细节。这样就可以降低应用程序的复杂度。并且提高程序的可维护性。
外观模式的关键特征:
意图:简化原有系统的使用方式,需要定义自己的接口。
问题:字需要使用某个复杂系统的一些子系统,或者需要以一种特殊的方式与系统进行交互。如何降低各个系统之间的依赖关系?降低复杂度?
解决方案:Facade为原有系统提供了一个新的接口,我们通过这个接口来使用该系统的某些子系统的功能。
外观模式的适用以下情况:
1.不需要适用一个复杂系统的所有功能,而且可以创建一个新的类,包含访问系统的所有规则。如果只需要使用系统的部分功能,那么你为新类创建API将比原系统的要少的多。
2.希望封装或者隐藏原有系统。
3.希望使用原系统的功能,而且还希望增加一些新的功能。
4.希望新类的成本小于所有人学会使用或者未来维护原系统所需要的成本。
实现:
例:现在你家里有一些电器,你出门之间需要把这些电器关闭掉。(马上交不起电费了)那么问题来了。你需要先去关灯,然后去关电脑等等。
这里,家就可以看做一个系统,而关闭各个电器可以看做该系统的各个子系统。那么我们就可以设计一个总开关,来使用你需要的功能。
假设你现在需要关闭灯和电脑:
代码实现:
Facade.h:
#ifndef FACADE_H_
#define FACADE_H_
class Bulb //灯
{
public:
Bulb();
~Bulb();
void ShutDown();
};
class Computer //电脑
{
public:
Computer();
~Computer();
void ShutDown();
};
class CFacade //外观
{
public:
CFacade();
~CFacade();
Bulb* myBulb;
Computer* myComputer;
void AllShutDown();
};
#endif // !FACADE_H_
Facade.cpp
#include"Facade.h"
#include<iostream>
using namespace std;
Bulb::Bulb()
{
}
Bulb::~Bulb()
{
}
void Bulb::ShutDown() //关灯
{
cout << "Bulb ShutDown" << endl;
}
Computer::Computer()
{
}
Computer::~Computer()
{
}
void Computer::ShutDown() //关电脑
{
cout << "Computer ShutDown" << endl;
}
CFacade::CFacade()
{
myBulb = new Bulb();
myComputer = new Computer();
}
CFacade::~CFacade() //析构
{
delete myBulb;
delete myComputer;
myBulb = NULL;
myComputer = NULL;
}
void CFacade::AllShutDown() //Facade类来调用系统的子系统功能
{
myBulb->ShutDown();
myComputer->ShutDown();
}
Main.cpp
#include "Facade.h"
#include <iostream>
using namespace std;
int main()
{
CFacade* myFacade = new CFacade();
myFacade->AllShutDown(); //关电器
return 0;
}
总结:
1)根据“单一职责原则”,在软件中将一个系统划分为若干个子系统有利于降低整个系统的复杂性,一个常见的设计目标是使子系统间的通信和相互依赖关系达到最小,而达到该目标的途径之一就是引入一个外观对象,它为子系统的访问提供了一个简单而单一的入口。
2)外观模式也是“迪米特法则”的体现,通过引入一个新的外观类可以降低原有系统的复杂度,外观类充当了客户类与子系统类之间的“第三者”,同时降低客户类与子系统类的耦合度。外观模式就是实现代码重构以便达到“迪米特法则”要求的一个强有力的武器。
3)外观模式要求一个子系统的外部与其内部的通信通过一个统一的外观对象进行,外观类将客户端与子系统的内部复杂性分隔开,使得客户端只需要与外观对象打交道,而不需要与子系统内部的很多对象打交道。
4)外观模式从很大程度上提高了客户端使用的便捷性,使得客户端无须关心子系统的工作细节,通过外观角色即可调用相关功能。
一定注意:
不要试图通过外观类为子系统增加新行为 ,不要通过继承一个外观类在子系统中加入新的行为,这种做法是错误的。外观模式的用意是为子系统提供一个集中化和简化的沟通渠道,而不是向子系统加入新的行为,新的行为的增加应该通过修改原有子系统类或增加新的子系统类来实现,不能通过外观类来实现。