这次不先说例子了,先看看一看外观模式的定义吧:
外观模式:提供了一个统一的接口,用来访问子系统中的一群接口。外观定义了一个高层接口,让子系统更容易使用。
在软件开发系统中,客户程序经常会与复杂系统的内部子系统之间产生耦合,而导致客户程序随着子系统的变化而变化。那么如何简化客户程序与子系统之间的交互接口?如何将复杂系统的内部子系统与客户程序之间的依赖解耦?这就是外观模式的作用了,我们通过一个外观类定义一个高层接口,该接口中包含子系统的中的接口,这样客户端只需要通过外观类访问各种子系统就可以啦。结构图表示如下:
看看这个例子:生活中,人们多多少少都玩过股票吧,那么大家知道股票和基金有什么区别吗?股票的风险大,盈利高,但是一般的股民没有专业的知识则盈利的可能性较低。于是有了一批人,开始购买基金,因为基金风险低,盈利又比银行利率可观。那么大家知道这是为什么吗?基金背后是怎么运作的呢?实际上是:我们客户买基金,钱给他们,他们拿着这个钱去买股票,买债券等等来进行钱生钱的活动,相比之下他们有专业的团队,盈利的可能性更大,所以基金就有了存在的意义。对比一下外观模式的定义,是不是发现这和外观模式是极其的吻合呢?基金就是这个外观啊!!看看我们如何完成应用外观模式的代码吧。(例子参考了《大话设计模式》)
2.外观模式实现
外观模式的代码如下:
//股票1类
class Stock1
{
public:
void Sell();
void Buy();
};
//股票2类
class Stock2
{
public:
void Sell();
void Buy();
};
//国债1
class NationalDebt1
{
public:
void Sell();
void Buy();
};
//外观类
class FundFacade
{
Stock1 *stock1;
Stock2 *stock2;
NationalDebt1 *national_debt1;
public:
FundFacade()
{
stock1 = new Stock1();
stock2 = new Stock2();
national_debt1 = new NationalDebt1();
}
void BuyMethod1()
{
stock1->Buy();
national_debt1->Buy();
}
void BuyMethod2()
{
stock2->Buy();
national_debt1->Buy();
}
};
通过外观模式客户端只需要访问FundFacade类中的成员就可以了,并不需要与具体的每个Stock1,Stock2和 NationalDebt1 相关联。这大大降低了耦合性,同时也使得系统容易维护,易于扩展。若需要扩展股票类,只需要加入Stock类;若有了新的购买方案,只需要在FundFacade 类中加一个BuyMethod方法。
3.使用外观模式的场合和好处
(1)在设计初期阶段,应该有意识的将不同的两个层分离,比如经典的三层架构,就需要考虑在数据访问层、业务逻辑层和表示层的层与层之间建立外观,这样可以为复杂的子系统提供一个简单的接口,使得耦合性大大的降低。
(2)在开发阶段,子系统往往因为不断的重构演化而变得原来越复杂,大多数的模式使用时也都会产生很多很小的类,这本是好事,但也给外部调用它们的用户程序带来了使用上的困难,增加外观可以提供一个简单的接口,减少它们之间的依赖。
(3)在维护一个遗留的一个大型系统时,可能这个系统已经非常难以维护和扩展了,但是因为它包含非常重要的功能,新的系统开发必须依赖它,这时也可以应用外观模式。可以为新系统开发一个外观类,来提供粗糙和高度复杂的遗留代码的比较清晰、简单的接口,让新系统与外观类对象交互,外观类负责与遗留代码交互所有复杂的工作。这样分两个小组,一个小组开发外观类与老系统的交互,另一个小组只要了解外观类的接口,直接开发新系统调用这些接口就可以了。