外观模式Facade(门面模式):为系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这个子系统更加容易使用。它完美的体现了迪米特原则和依赖倒转原则,是非常常用的设计模式之一。
对于书上举得买股票和基金的例子。炒股新手由于对证券知识不是完全了解,再加上股票种类众多,这种情况下很容易赔钱。而购买基金却减少很多风险,此时并不需要对股票有过多的了解,甚至可以对股票一无所知,仅仅关注基金的上涨和下跌,而实际的操作却由基金经理与上千只股票打交道。
代码:
#include<iostream>
using namespace std;
class Stock1
{
public:
Stock1()
{
}
void buy()
{
cout<<"buy stock 1!"<<endl;
}
void sell()
{
cout<<"sell stock 1"<<endl;
}
};
class Stock2
{
public:
Stock2()
{
}
void buy()
{
cout<<"buy stock 2!"<<endl;
}
void sell()
{
cout<<"sell stock 2"<<endl;
}
};
class Stock3
{
public:
Stock3()
{
}
void buy()
{
cout<<"buy stock 3!"<<endl;
}
void sell()
{
cout<<"sell stock 3"<<endl;
}
};
class Fund//外观类,封装对各种股票的各种操作。
{
public:
Stock1 *stock1;
Stock2 *stock2;
Stock3 *stock3;
public:
Fund()
{
stock1=new Stock1;
stock2=new Stock2;
stock3=new Stock3;
}
void sell()
{
stock1->sell();
stock2->sell();
stock3->sell();
}
void buy()
{
stock1->buy();
stock2->buy();
stock3->buy();
}
};
int main(int argc,char**argv)
{
Fund *fund=new Fund;
fund->buy();
fund->sell();
return 0;
}
外观模式使用的时机
首先,在设计的初期,应该有意识的将不同的两个层分离。比如经典的三层构架,就需要考虑在数据访问层和业务逻辑层,业务逻辑层和表示层层与层之间使用外观模式,这样就可以为复杂的子系统提供简单的接口,使得耦合性大大降低。
其次,在开发阶段,子系统往往因为不断的重构演化而变得越来越复杂。大多数设计模式会产生很多很小的类,这本是好事,但这也给外部调用它们的客户程序带来使用上的困难。使用外观模式提供简单接口,减少它们之间的依赖。
第三,在维护一个遗留的大型系统时,可能这个系统已经变得非常难以维护和扩展。因为它包含非常重要的功能,新的需求开发必须依赖它,这时候使用外观模式也很合适,使用外观模式为设计粗糙或是高度复杂的遗留代码提供简单的接口。让外观类提供与遗留代码交互的功能。