- 1. 理论基础
- 2. 模板代码
- 3. 应用
- 3.1 基金操作
什么时候使用外观模式好呢?
- 首先在设计初期, 应该要有意识的将不同的两层进行分离, 比如经典三层架构, 就需要考虑数据访问层和业务逻辑层, 表示层的层与层之间建立外观facede, 这样可以为复杂的子系统提供一个简单地接口, 使得耦合大大降低
- 其次, 开发阶段, 子系统往往因为不断重构演化而变得越来越复杂, 大多数的模式使用都会产生很多很小的类, 这本是好事情, 但是也给外部调用的客户带来了使用的困难, 因此增加外观Facede, 可以提供一个简单地接口, 减少他们的依赖
- 最后, 维护一个遗留的大型系统时, 可能这个系统已经非常难以维护和扩展了, 但因为他们包含了非常重要的功能, 新的需求开发必须依赖他们, 这时候外观模式facede就非常合适了, 可以为新系统开发一个外观facede类, 来提供设计粗糙或者高度复杂的遗留代码的比较清晰的简单接口, 让新系统与这个facede对象交互, facede与遗留代码交互所有复杂的工作
外观模式:
为子系统中的一组接口提供一个一致的界面, 此模式定义了一个高层接口, 这个接口使得这一子系统更加容易使用
主要解决:
降低访问复杂系统的内部子系统时的复杂度,简化客户端之间的接口。
何时使用:
- 客户端不需要知道系统内部的复杂联系,整个系统只需提供一个"接待员"即可。
- 定义系统的入口。
如何解决:
客户端不与系统耦合,外观类与系统耦合。
关键代码:
在客户端和复杂系统之间再加一层,这一层将调用顺序、依赖关系等处理好。
应用实例:
1、去医院看病,可能要去挂号、门诊、划价、取药,让患者或患者家属觉得很复杂,如果有提供接待人员,只让接待人员来处理,就很方便。
2、标准三层开发模式。
3、想要炒股缺不太清除里面的门道, 因此选择基金进行炒股, 也就是找个搭理人(基金经理)来操控, 我只需要知道基金的买进卖出就行了(下文有代码实现)
优点:
1、减少系统相互依赖。
2、提高灵活性。
3、提高了安全性。
缺点:
不符合开闭原则,如果要改东西很麻烦,继承重写都不合适。
使用场景:
1、为复杂的模块或子系统提供外界访问的模块。
2、子系统相对独立。
3、预防低水平人员带来的风险。
注意事项:
在层次化结构中,可以使用外观模式定义系统中每一层的入口。
// 子系统类
class SubSystem1{
public:
void methodOne(){
cout << "子系统方法 一" <methodOne();
two->methodTow();
four->methodFour();
three->methodThree();
}
void methodB(){
cout << "方法组B() ..." <methodOne();
four->methodFour();
three->methodThree();
two->methodTow();
}
};
int main(int argc, char const *argv[]){
Facede *facede = new Facede();
facede->methodA(); // 由于facede的作用, 客户端根本不知道三个子系统类的存在
delete facede;
return 0;
}
3. 应用
3.1 基金操作
该应用不仅涉及到了外观模式的相关知识,
同时也涵盖多态的使用事项, 比如基类的析构函数设置为虚函数
还有对象数组的构建, 初始化, 以及回收内存的方式
class Stocks{
public:
virtual ~Stocks(){}
// 注意基类的析构函数设置为虚函数, 才能在多态过程中回收派生类的内存空间,
// 这是因为父类指针指向子类对象时, 回收父类指针,
// 会根据多态virtual虚函数指针找到父类虚函数(析构函数), 才能匹配到子类的析构函数
virtual void Sell(){}
virtual void Buy(){}
// 纯虚函数是无法实例化, 所以这里定义称为虚函数即可
// virtual void Sell() = 0;
// virtual void Buy() = 0;
};
// 股票1
class Stock1 : public Stocks{
public:
~Stock1(){
cout << "回收了.. ." <Buy();
}
cout << "买进基金完成 ... n" << endl;
}
void SellFund(){
for(int i=0; i<5; i++){
stocks[i]->Sell();
}
cout << "卖出基金完成 ... n" << endl;
}
};
int main(int argc, char const *argv[]){
Fund *f1 = new Fund();
f1->BuyFund();
f1->SellFund();
delete f1;
return 0;
}



