總覽
我將通過對(duì)外觀模式
(Facade Pattern)
的講解來開始我們對(duì)設(shè)計(jì)模式的學(xué)習(xí)。也許在過去你就已經(jīng)使用到了外觀設(shè)計(jì)模式只是你并未曾注意到。
在這一章里將包含以下的一些內(nèi)容:
l?????????
什么是外觀設(shè)計(jì)模式
(Facade Pattern)
及其用途
l?????????
指出
Facade
模式的主要功能
l?????????
提出
Facade
模式的一些變化
Facade
模式的基本介紹
在
GoF
的《設(shè)計(jì)模式》一書中提到,使用
Facade
模式的目的是:給子系統(tǒng)的系列接口提供一個(gè)統(tǒng)一的外部接口。使用
Facade
模式就是定義一個(gè)
Facade
接口,她是一個(gè)可以使原來的子系統(tǒng)更加容易被我們使用的高級(jí)接口。
也就是說,我們需要和一個(gè)比當(dāng)前系統(tǒng)所提供的方法要更加簡(jiǎn)單的系統(tǒng)進(jìn)行交互,或者說我們需要用某種特定的方式來使用當(dāng)前系統(tǒng)
(
比如把一個(gè)
3D
的繪圖程序作為
2D
的繪圖程序來使用
)
。我們可以建立這樣的方法因?yàn)槲覀冎恍枰褂玫疆?dāng)前系統(tǒng)的一部分功能。
正式學(xué)習(xí)
Facade
模式
曾經(jīng),我在一個(gè)大型的工程制造工廠里負(fù)責(zé)工程承包的工作。在我工作的第一天,這個(gè)項(xiàng)目的技術(shù)帶頭人不在。但是,我不可能白拿薪水,客戶想給我找點(diǎn)事情干,盡管這些事情毫無意義。難道,你沒有遇見過這樣的情況嗎?
因此,該項(xiàng)目組的一個(gè)人還真給我找了點(diǎn)事做。她說:“你將會(huì)學(xué)習(xí)到我們會(huì)使用到的
CAD/CAM
系統(tǒng),也許現(xiàn)在你就可以開始學(xué)習(xí)了。就從這些手冊(cè)開始吧!”然后,她把我?guī)У揭淮蠖训奈臋n前。不是我夸張,有
8
英尺這么長(zhǎng)的手冊(cè)擺在書架上等著我去閱讀,而且這些手冊(cè)都是
8.5
×
11
英寸大小,還是小號(hào)字印刷的!這真是一個(gè)復(fù)雜的系統(tǒng)。
那么,我,或者說我和你,或者更多人,假如我們將會(huì)在一個(gè)項(xiàng)目中用到剛才的這個(gè)
CAD/CAM
系統(tǒng),我們?cè)撛趺崔k?是我們每個(gè)人都學(xué)習(xí)到底如何使用這個(gè)系統(tǒng)嗎?還是說我們先把我們要用到功能提出來,然后由一個(gè)人來編寫某些特定的接口來使用這個(gè)系統(tǒng),而剩下的人只需要知道如何使用這些特定的接口就可以了呢?
這個(gè)編寫接口的人將決定我和我們項(xiàng)目組的其他人將如何使用這個(gè)系統(tǒng),將決定我們用什么樣的
API
來完美的完成工作。她將會(huì)根據(jù)我們的需要?jiǎng)?chuàng)建一個(gè)或者多個(gè)的類
(Facade class)
。我和其他同事就只使用她創(chuàng)建的這些類而不用去學(xué)習(xí)這整個(gè)復(fù)雜的系統(tǒng)了。
這種方式只適合在我們只用到這個(gè)系統(tǒng)的一部分功能或者只用某種特定方式來使用這個(gè)系統(tǒng)的時(shí)候。如果系統(tǒng)中的所有功能都要被用到,那么更好的設(shè)計(jì)方案將會(huì)是考慮當(dāng)前系統(tǒng)是否是最值得我們使用的。
這就是外觀設(shè)計(jì)模式
(Facade Pattern)
。她讓我們可以更方便地使用那些相當(dāng)復(fù)雜的系統(tǒng)。雖然我們有一個(gè)非常復(fù)雜的系統(tǒng),但是,我們僅僅需要其中的一部分功能,或者我們以某個(gè)特定方式來使用這些功能。怎樣,通過
Facade
模式的使用,我們將會(huì)得到一個(gè)非常易用或者更滿足我們需要的系統(tǒng)。
大多數(shù)工作仍然將會(huì)被底層的原始系統(tǒng)來完成。前面講到的我們自己編寫的
Facade class
將提供一些很容易理解的方法供我們使用。這些方法使用底層的原始的系統(tǒng)來完成我們新定義的功能。
?
Facade
模式不僅僅可以用來創(chuàng)建更簡(jiǎn)單的方法調(diào)用,還可以用來減少客戶對(duì)象需要操縱的對(duì)象的個(gè)數(shù)。例如:假設(shè)我有一個(gè)
Client
類的對(duì)象,它必須打開一個(gè)
Database
,并從中取得一個(gè)
Model
。然后通過
Model
查詢得到一個(gè)
Element
。最后,
Client
還要從
Element
里面得到自己需要的信息。這肯定是一個(gè)很復(fù)雜的過程。如果,我們建立一個(gè)
DatabaseFacade
的中間類,
Client
通過它來完成上述的一系列工作,這一切將變得簡(jiǎn)單的多。請(qǐng)看下面的
UML
圖。

如果我們的
Facade class
是無狀態(tài)的類
(
也就是說它里面不保存任何和狀態(tài)有關(guān)的量
)
,一個(gè)
Facade
的對(duì)象可以同時(shí)被多個(gè)其他的對(duì)象使用。隨后,在
21
章,我們將學(xué)習(xí)如何通過使用
Singleton
模式和
Double-Checked Locking
模式來實(shí)現(xiàn)這個(gè)功能。
?
設(shè)想,除了使用當(dāng)前系統(tǒng)內(nèi)的功能以外,我們還提供一些新的功能-比如,把所有程序調(diào)用過程記錄到一個(gè)事務(wù)里面。這樣,我們所使用的功能超出了當(dāng)前系統(tǒng)的功能。
這種情況下,我們可以通過向
Facade
類里添加其他的一些方法
(method)
來擴(kuò)展其功能。這仍然是
Facade
模式,只是她原有的功能得到擴(kuò)展。我們的主要目標(biāo)是簡(jiǎn)化方法的調(diào)用因?yàn)槲覀儾⒉幌M蛻舳顺绦蛑勒{(diào)用哪些額外的方法-這一切都通過
Facade
來完成了。
Facade
模式給我們一個(gè)普遍的使用方法。在本模式中的
Facade
類的實(shí)質(zhì)就是我們?yōu)榭蛻舳藙?chuàng)建新的接口,而不是去繼續(xù)使用原有的接口。我們可以這樣做,是因?yàn)槲覀儾恍枰褂迷枷到y(tǒng)中的所有方法。
Facade
模式還可以用來隱藏或封裝原來的系統(tǒng)。
Facade
類可以把原來的系統(tǒng)當(dāng)成私有變量。這樣,原始系統(tǒng)就僅僅和
Facade
類有聯(lián)系而不會(huì)暴露給
Facade
類的使用者。
正如下面將要提到的,我們有很多理由來封裝系統(tǒng):
l?????????
追蹤系統(tǒng)使用
-通過限制所有對(duì)系統(tǒng)功能的調(diào)用必須由
Facade
類來完成,我們可以非常方便地監(jiān)視系統(tǒng)使用狀況。
l?????????
在系統(tǒng)間進(jìn)行切換
-有可能在將來我們所使用的系統(tǒng)會(huì)有所改變。通過把原始系統(tǒng)當(dāng)成
Facade
類的私有成員變量
(private member)
來處理,我們可以很輕易的切換我們所使用的系統(tǒng)。當(dāng)然,也許仍然有巨大的工作量,但是至少,我只需要改變一個(gè)地方
(Facade
類
)
。
總結(jié)
外觀模式
(Facade Pattern)
名稱的得來是因?yàn)樗谠枷到y(tǒng)的前面建立了一個(gè)新的接口
(Facade
類
)
。
我們將在以下的情況中使用到
Facade
模式:
l?????????
當(dāng)不需要使用一個(gè)復(fù)雜系統(tǒng)的所有功能時(shí)。創(chuàng)建一個(gè)類來包含所有使用這個(gè)系統(tǒng)的規(guī)則、方法。通常,我們會(huì)用到一個(gè)原始系統(tǒng)的子系統(tǒng),新創(chuàng)建的類的接口
(API)
將會(huì)比原始系統(tǒng)的接口
(API)
簡(jiǎn)單得多。
l?????????
當(dāng)想要封裝或隱藏原始系統(tǒng)時(shí)。
l?????????
當(dāng)想要使用原始系統(tǒng)的某些功能并添加新功能時(shí)。
l?????????
當(dāng)編寫新類的花費(fèi)要低于項(xiàng)目組每個(gè)人都學(xué)習(xí)如何使用原始系統(tǒng)或者低于在后期維護(hù)時(shí)的投入的時(shí)候。
=========================原文===========================
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.
?
posted on 2006-10-25 13:55
xiaosilent 閱讀(1918)
評(píng)論(5) 編輯 收藏 所屬分類:
設(shè)計(jì)模式