[译]外观设计模式(The Facade Pattern) From Chapter 6 of《Design Patterns Explained》

[译]外观设计模式(The Facade Pattern) From Chapter 6 of《Design Patterns Explained》

总览

我将通过对外观模式 (Facade Pattern) 的讲解来开始我们对设计模式的学习。也许在过去你就已经使用到了外观设计模式只是你并未曾注意到。

在这一章里将包含以下的一些内容:

l          什么是外观设计模式 (Facade Pattern) 及其用途

l          指出 Facade 模式的主要功能

l          提出 Facade 模式的一些变化

Facade 模式的基本介绍

GoF 的《设计模式》一书中提到,使用 Facade 模式的目的是:给子系统的系列接口提供一个统一的外部接口。使用 Facade 模式就是定义一个 Facade 接口,她是一个可以使原来的子系统更加容易被我们使用的高级接口。

也就是说,我们需要和一个比当前系统所提供的方法要更加简单的系统进行交互,或者说我们需要用某种特定的方式来使用当前系统 ( 比如把一个 3D 的绘图程序作为 2D 的绘图程序来使用 ) 。我们可以建立这样的方法因为我们只需要使用到当前系统的一部分功能。

正式学习 Facade 模式

曾经,我在一个大型的工程制造工厂里负责工程承包的工作。在我工作的第一天,这个项目的技术带头人不在。但是,我不可能白拿薪水,客户想给我找点事情干,尽管这些事情毫无意义。难道,你没有遇见过这样的情况吗?

因此,该项目组的一个人还真给我找了点事做。她说:“你将会学习到我们会使用到的 CAD/CAM 系统,也许现在你就可以开始学习了。就从这些手册开始吧!”然后,她把我带到一大堆的文档前。不是我夸张,有 8 英尺这么长的手册摆在书架上等着我去阅读,而且这些手册都是 8.5 × 11 英寸大小,还是小号字印刷的!这真是一个复杂的系统。

那么,我,或者说我和你,或者更多人,假如我们将会在一个项目中用到刚才的这个 CAD/CAM 系统,我们该怎么办?是我们每个人都学习到底如何使用这个系统吗?还是说我们先把我们要用到功能提出来,然后由一个人来编写某些特定的接口来使用这个系统,而剩下的人只需要知道如何使用这些特定的接口就可以了呢?

这个编写接口的人将决定我和我们项目组的其他人将如何使用这个系统,将决定我们用什么样的 API 来完美的完成工作。她将会根据我们的需要创建一个或者多个的类 (Facade class) 。我和其他同事就只使用她创建的这些类而不用去学习这整个复杂的系统了。

这种方式只适合在我们只用到这个系统的一部分功能或者只用某种特定方式来使用这个系统的时候。如果系统中的所有功能都要被用到,那么更好的设计方案将会是考虑当前系统是否是最值得我们使用的。

这就是外观设计模式 (Facade Pattern) 。她让我们可以更方便地使用那些相当复杂的系统。虽然我们有一个非常复杂的系统,但是,我们仅仅需要其中的一部分功能,或者我们以某个特定方式来使用这些功能。怎样,通过 Facade 模式的使用,我们将会得到一个非常易用或者更满足我们需要的系统。

大多数工作仍然将会被底层的原始系统来完成。前面讲到的我们自己编写的 Facade class 将提供一些很容易理解的方法供我们使用。这些方法使用底层的原始的系统来完成我们新定义的功能。

 

Facade 模式不仅仅可以用来创建更简单的方法调用,还可以用来减少客户对象需要操纵的对象的个数。例如:假设我有一个 Client 类的对象,它必须打开一个 Database ,并从中取得一个 Model 。然后通过 Model 查询得到一个 Element 。最后, Client 还要从 Element 里面得到自己需要的信息。这肯定是一个很复杂的过程。如果,我们建立一个 DatabaseFacade 的中间类, Client 通过它来完成上述的一系列工作,这一切将变得简单的多。请看下面的 UML 图。

如果我们的 Facade class 是无状态的类 ( 也就是说它里面不保存任何和状态有关的量 ) ,一个 Facade 的对象可以同时被多个其他的对象使用。随后,在 21 章,我们将学习如何通过使用 Singleton 模式和 Double-Checked Locking 模式来实现这个功能。

 

设想,除了使用当前系统内的功能以外,我们还提供一些新的功能-比如,把所有程序调用过程记录到一个事务里面。这样,我们所使用的功能超出了当前系统的功能。

这种情况下,我们可以通过向 Facade 类里添加其他的一些方法 (method) 来扩展其功能。这仍然是 Facade 模式,只是她原有的功能得到扩展。我们的主要目标是简化方法的调用因为我们并不希望客户端程序知道调用哪些额外的方法-这一切都通过 Facade 来完成了。

Facade 模式给我们一个普遍的使用方法。在本模式中的 Facade 类的实质就是我们为客户端创建新的接口,而不是去继续使用原有的接口。我们可以这样做,是因为我们不需要使用原始系统中的所有方法。

Facade 模式还可以用来隐藏或封装原来的系统。 Facade 类可以把原来的系统当成私有变量。这样,原始系统就仅仅和 Facade 类有联系而不会暴露给 Facade 类的使用者。

正如下面将要提到的,我们有很多理由来封装系统:

l          追踪系统使用 -通过限制所有对系统功能的调用必须由 Facade 类来完成,我们可以非常方便地监视系统使用状况。

l          在系统间进行切换 -有可能在将来我们所使用的系统会有所改变。通过把原始系统当成 Facade 类的私有成员变量 (private member) 来处理,我们可以很轻易的切换我们所使用的系统。当然,也许仍然有巨大的工作量,但是至少,我只需要改变一个地方 (Facade )

总结

外观模式 (Facade Pattern) 名称的得来是因为她在原始系统的前面建立了一个新的接口 (Facade )

我们将在以下的情况中使用到 Facade 模式:

l          当不需要使用一个复杂系统的所有功能时。创建一个类来包含所有使用这个系统的规则、方法。通常,我们会用到一个原始系统的子系统,新创建的类的接口 (API) 将会比原始系统的接口 (API) 简单得多。

l          当想要封装或隐藏原始系统时。

l          当想要使用原始系统的某些功能并添加新功能时。

l          当编写新类的花费要低于项目组每个人都学习如何使用原始系统或者低于在后期维护时的投入的时候。




=========================原文===========================

The Facade Pattern

Overview

I start the study of design patterns with a pattern that you have probably implemented in the past but may not have had a name for: the Façade pattern.

This chapter

l         Explains what the Façade pattern is and where it is used.

l         Presents the key features of the pattern.

l         Presents some variations on the Façade pattern.

l         Relates the Façade pattern to the CAD/CAM problem.

 

Introducing the Facade Pattern

According to the Gang of Four, the intent of the Façade pattern is to provide a unified interface to a set of interfaces in a subsystem. Façade pattern defines a higher-level interface that makes the subsystem easier to use.

Basically, this is saying that we need to interact with a system that is easier than the current method, or we need to use the system in a particular way(such as using a 3D drawing program in a 2D way). We can build such a method of interaction because we only need to use a subset of the system in question.

 

Learning the Facade Pattern

Once, I worked as a contractor for a large engineering and manufacturing company. My first day on the job, the technical lead of the project was not in. Now, this client did not want to pay me by the hour and not have anything for me to do. They wanted me to be doing something, even if it was not useful! Haven’t you had days like this?

So, one of the project members found something for me to do. She said, “You are going to have to learn the CAD/CAM system we use sometime, so you might as well start now. Start with these manuals over here.” Then she took me to the set of documentation. I am not making this up: There were 8 feet for manuals for me to read---each page 8.5 × 11 inches and in small print! This was one complex system!

Now, if you and I and say another four or five people were on a project that needed to use this system, what approach would we take? Would we all learn the system? Or would we draw straws and the loser would hare to write routines that the rest of us would use to interface with the system?

This person would determine how I and others on our team were going to use the system and what application programming interface (API) would be best for our particular needs. She would then create a new class or classes that had the interface we required. Then I and the rest of the programming community could use this new interface without having to learn the entire complicated system..

This approach works only when using a subset of the system’s capabilities or when interacting with it in a particular way. If everything in the system needs to be used, the only way to improve the design would be if it were poor in the first place.

This is the Facade pattern. It enables us to use a complex system more easily, either to use just a subset of the system or use the system in a particular way. We have a complicated system of which we need to use only a part. We end up with a simpler, easier-to-use system or one that is customized to our needs.

Most of the work still needs to be done by the underlying system. The Facade provides a collection of easier-to-understanding methods. These methods use the underlying system to implement the newly defined functions.

 

Fields Notes: The Facade Pattern

Facades can be used not only to create a simpler interface in terms of method calls, but also to reduce the number of objects that a client object must deal with. For example, suppose I have a Client object that must deal with Database, Models, and Elements. The Client must first open the Database and get a Model. Then it queries the Model to get an Element. Finally, it asks the Element for information. It might be a lot easier to create a DatabaseFacade that could be queried by the Client (see Figure 6-4)

 

Figure 6-4

If a Facade can be made to be stateless (that is, no state is stored in it), one Facade object can be used by several other objects. Later, in Chapter 21, I show you how to do this, using the Singleton pattern and the Double-Checked Locking Pattern.

Suppose that in addition to using functions that are in the system, I also need to provide some new functionality say, record all calls to specific routines. In this case, I am going beyond a simple subset of the system.

In this case, the methods I write for the Facade class may b supplemented by new routines for the new functionality. This is still the Facade pattern, but expanded with new functionality. I consider the primary goal one of simplification because I don’t want to have to force the client routine to know that it needs to call the extra routines the Facade does that.

The Facade pattern set the general approach; it got me started. The Facade part of the pattern is the fact that I am creating a new interface for the client to use instead of the existing system’s interface. I can do this because the Client object does not need to use all of the functions in my original system.

The Facade can also be used to hide, or encapsulate, the system. The Facade could contain the system as private members of the Facade class. In this case, the original system would be linked in with the Facade class, but not presented to users of the Facade class.

There are a number of reasons to encapsulate the system, including the following:

l         Track system usage By forcing all accesses to the system to go through the Facade, I can easily monitor system usage.

l         Swap out systems I may need to switch systems in the future. By making the original system a private member of the Facade class, I can swap out the system for a new one with minimal effort. There may still be a significant amount of effort required, but at least I will only have to change the code in one place (the Facade class).

 

Summary

The Facade pattern is so named because it puts up a new interface (a facade) in front of the original system.

The Facade pattern applies when

l         You do not need to use all the functionality of a complex system and can create a new class that contains all the rules for accessing that system. If this is a subset of the original system, as it usually is, the API that you create for the new class should be much simpler than the original system’s API.

l         You want to encapsulate or hide the original system.

l         You want to use the functionality of the original system and want to ad some new functionality as well.

l         The cost of writing this new class is less than the cost of everybody learning how to use the original system or is less than you would spend on maintenance in the future.

 

你可能感兴趣的:([译]外观设计模式(The Facade Pattern) From Chapter 6 of《Design Patterns Explained》)