《设计模式解析》第6章 Facade(外表)模式

来源:互联网 发布:2015软件评测师真题 编辑:程序博客网 时间:2024/04/25 23:19

6

 

Facade(外表)模式

 

概述

       我将从Façade模式开始学习设计模式,或许此前你已经实现过该模式,但却没有为它取一个名字。

 

 

 

       在本章,

 

 

 

l           我解释什么是Façade模式以及在哪里使用它。

 

 

 

l           我介绍Façade模式的关键特性。

 

 

 

l           我介绍Façade模式的一些变种。

 

 

 

l           我将Façade模式和CAD/CAM问题关联起来。

 

 

 

Façade模式介绍

       依据四人团的意思,Façade模式的意图是:

 

 

 

       “为子系统中的一组接口提供一个统一的接口。Façade定义了一个更高层次的接口,使得子系统更加容易使用。”

 

 

 

       基本上,这就是说我们需要一个新的方法去和一个系统交互,该方法比当前的方法更加容易,或者我们需要以一种特殊的方式来使用系统(例如以二维的方式来使用一个三维的绘图程序)。我们之所以能够构建这样的交互方法,是因为对于我们所讨论的这个系统,我们只需要使用它的一个子集。

 

 

 

学习Facade模式

有一次,我以承包人的身份为一家大型工程制造公司工作。在我上班的第一天,项目的技术领导没有来。现在,这个客户不想按小时来支付我的薪水,也没有任何事情让我做。他们希望我在做些什么,即便它没有任何用处!难道你没有体验过这样的日子吗?

 

 

 

于是,一个项目成员发现了我可以做的事情。她说,“在未来的某个时候,你将不得不学习我们使用的这个CAD/CAM系统,因此你最好现在就开始,从这边的这些手册开始。”于是她把我带到那组文档前面。我可以毫不夸张地说:有8英尺的手册等着我去阅读……每页8.11英寸,并且还是小字体!这是一个复杂的系统!

 

 

 

6-1 8英尺的手册 = 一个复杂的系统!

 

 

 

现在,如果你和我,并且假设还有另外四五个人在一个需要使用这个系统的项目中,不是我们所有的人都必须学习整个系统。为了不浪费每个人的时间,我们可能会抽签,输家将不得不写程序,而其他的人则使用它来和系统交互

 

 

 

这个人将决定我和团队中的其他成员如何使用系统,以及什么样的API最适合我们的特殊需求。接下来她将会创建一个或多个新的类,后者拥有我们所需要的接口。这样,我和其他的程序员就可以使用这个新的接口而不需要完整地学习这个复杂的系统(见图6-2)。

 

 

 

6-2 将客户与子系统隔离开来

 

 

 

现在,这种方法仅仅在使用系统能力的一个子集或者以一种特殊方式和系统交互的时候有效。如果系统中的每一样东西都需要被使用,那么我将不可能提出一个简单的接口(除非原先的设计人员做得很糟糕)。

 

 

 

这就是Façade模式。它使得我们更加容易地使用一个复杂的系统,要么仅仅使用系统的一个子集,要么以一种特殊的方式来使用系统。我们拥有一个复杂的系统,我们只需要使用它的一部分。我们最终将得到一个更简单的、更容易使用的系统,或是一个针对我们的需求而定制的系统。

 

 

 

大部分的工作仍旧需要由底层系统来完成。Façade提供一组更加容易理解的方法。这些方法使用底层系统实现新定义的功能。

 

 

 

Façade模式:关键特性

 

 

 

意图

 

 

 

 

 

你想要简化一个现有系统的使用。你需要定义你自己的接口。

 

 

 

 

 

问题

 

 

 

 

 

你只需要使用复杂系统的一个子集,或者你需要以一种特殊方式和系统交互。

 

 

 

 

 

方案

 

 

 

 

 

Façade给现有系统的客户一个新的接口去使用。

 

 

 

 

 

参与者和协作者

 

 

 

 

 

它给客户一个专门的接口,这使得它更容易使用。

 

 

 

 

 

结果

 

 

 

 

 

Façade简化了必需的子系统的使用。不过,由于Facede是不完整的,某些功能对客户可能不可用。

 

 

 

 

 

实现

 

 

 

 

 

l           定义一个(或几个)新类,后者拥有必需的接口。

 

 

 

l           让这个新类使用现有系统。

 

 

 

 

 

 

 

GoF参考

 

 

 

 

 

185-193页。

 

 

 

 

 

 

 

 

6-3 Façade模式标准的、简化的视图

 

 

 

野外记录:Façade模式

Façade不仅可用于通过方法调用创建一个更简单的接口,还能减少一个客户对象必须处理的对象的数目。例如,假设我有一个必须处理数据库、模型和元素的客户对象。该客户必须首先打开数据库并获取一个模型;接着,它查询这个模型得到一个元素;最后,它向这个元素请求信息。如果我们创建一个能被客户查询的数据库Façade,那么情况就会简单得多(见图6-4)。

 

 

6-4 Façade为客户减少对象数目

 

 

 

假设除了使用系统中已有的功能以外,我还需要提供一些新的功能。那么我要面对的就不再是一个简单的系统子集了。

 

 

 

此时,我为Façade类写的方法将会被新的程序实现以提供新的功能。这仍然是Façade模式,但是已被扩展了新的功能。

 

 

 

Façade模式提出了大体途径,它让我有了一个起点。该模式的外表部分是我正在创建一个新的接口给客户使用而不是使用现有系统接口的事实。我能够这样做是因为客户对象不需要使用原始系统中的全部功能。

 

 

 

模式提出了大体途径

 

 

 

一个模式仅仅设置了大体途径。是否增加新的功能取决于当前的情况。模式是蓝图,是起点而不是终点。

 

 

 

Façade也能用于隐藏或者封装系统。Façade能够包含系统作为Façade类的私有成员。此时,原始系统将会和Façade类一起连接进去,但该系统对Façade类的用户却不可见。

 

 

 

有许多封装系统的理由:

 

 

 

l           跟踪系统使用——通过迫使所有对系统的访问都流经Façade,我可以很容易地监视系统使用。

 

 

 

l           换出系统——将来我可能需要换出系统。通过将原始系统作为Façade类的一个私有成员,我只需花最小的代价换用一个新的系统。虽然工作量有可能仍然很大,但至少我将只需要在一个地方改变代码(Façade类)。

 

 

 

Façade模式和CAD/CAM问题关联起来

思考上面的例子。Façade模式会有助于诸如V1SlotsV1Holes之类的类来使用V1System。在第12章“用模式解决CAD/CAM问题”中的解决方案中,我将会这样做。

 

 

 

总结

Façade模式之所以被这样命名是因为它在原始系统的前面放置了一个新的前端(外表)。

 

 

 

Façade模式适用于以下时候:

 

 

 

l           你不需要使用一个复杂系统的全部功能,并且能够创建一个新类,它包含了所有访问该系统的全部规则。如果正如通常情况一样,这是原始系统的一个子集,那么你在新类中创建的API应该会比原始系统中的API简单很多。

 

 

 

l           你需要封装或者隐藏原始系统。

 

 

 

l           你需要使用原始系统的功能,并且同时想要增加一些新的功能。

 

 

 

l           写这个新类的代价小于每个人学习如何使用原始系统的代价,或者小于将来你在维护上可能花费的代价。