[摘錄]軟件的架構(gòu)與模式之經(jīng)典架構(gòu)模式簡介
本文摘自:
http://fanqiang.chinaunix.net/program/project/2005-06-16/3316.shtml
? 根據(jù)Linda Rising的《Pattern Almanac》一書,已知的架構(gòu)模式有七十多種。這是一個(gè)只多不少的統(tǒng)計(jì),其中包括了很多通常認(rèn)為是設(shè)計(jì)模式的模式,比如Bridge,F(xiàn)acade,Interpreter,Mediator等模式通常認(rèn)為是設(shè)計(jì)模式,但是在許多情況下,也可以作為架構(gòu)模式出現(xiàn),因此也常常被當(dāng)作架構(gòu)模式。
Layers架構(gòu)模式
在收集到用戶對軟件的要求之后,架構(gòu)設(shè)計(jì)就開始了。架構(gòu)設(shè)計(jì)一個(gè)主要的目的,就是把系統(tǒng)劃分成為很多"板塊"。劃分的方式通常有兩種,一種是橫向的劃分,一種是縱向劃分。
橫向劃分將系統(tǒng)按照商業(yè)目的劃分。比如一個(gè)書店的管理系統(tǒng)可以劃分成為進(jìn)貨、銷售、庫存管理、員工管理等等。
縱向劃分則不同,它按照抽象層次的高低,將系統(tǒng)劃分成"層",或叫Layer。比如一個(gè)公司的內(nèi)網(wǎng)管理系統(tǒng)通常可以劃分成為下面的幾個(gè)Layer:
一、網(wǎng)頁,也就是用戶界面,負(fù)責(zé)顯示數(shù)據(jù)、接受用戶輸入;
二、領(lǐng)域?qū)樱↗avaBean或者COM對象、B2B服務(wù)等,封裝了必要的商業(yè)邏輯,負(fù)責(zé)根據(jù)商業(yè)邏輯決定顯示什么數(shù)據(jù)、以及如何根據(jù)用戶輸入的數(shù)據(jù)進(jìn)行計(jì)算;
三、數(shù)據(jù)庫,負(fù)責(zé)存儲(chǔ)數(shù)據(jù),按照查詢要求提供所存儲(chǔ)的數(shù)據(jù)。
四、操作系統(tǒng)層,比如Windows NT或者Solaris等
五、硬件層,比如SUN E450服務(wù)器等
有人把這種Layer叫做Tier,但是Tier多帶有物理含義,不同的Tier往往位于不同的計(jì)算機(jī)上,由網(wǎng)絡(luò)連接起來,而Layer是純粹邏輯的概念,與物理劃分無關(guān)。
Layers架構(gòu)模式的好處是:
第一、任何一層的變化都可以很好地局限于這一層,而不會(huì)影響到其他各層。
第二、更容易容納新的技術(shù)和變化。Layers架構(gòu)模式容許任何一層變更所使用的技術(shù)
Fa?ade架構(gòu)模式
外部與一個(gè)子系統(tǒng)的通訊必須通過一個(gè)統(tǒng)一的門面(Facade)對象進(jìn)行,這就是Facade模式。
現(xiàn)代的軟件系統(tǒng)都是比較復(fù)雜的,設(shè)計(jì)模式的任務(wù)就是協(xié)助設(shè)計(jì)師處理復(fù)雜系統(tǒng)的設(shè)計(jì)。
設(shè)計(jì)師處理復(fù)雜系統(tǒng)的一個(gè)常見方法便是將其"分而治之",把一個(gè)系統(tǒng)劃分為幾個(gè)較小的子系統(tǒng)。但是這樣做了以后,設(shè)計(jì)師往往仍然會(huì)發(fā)現(xiàn)一個(gè)子系統(tǒng)內(nèi)仍然有太多的類型要處理。而使用一個(gè)子系統(tǒng)的使用端往往只關(guān)注一些特定的功能,卻要同時(shí)與子系統(tǒng)內(nèi)部的許多對象打交道后才能達(dá)到目的,請見下面的對象圖。
![]() 圖4、Facade架構(gòu)模式的結(jié)構(gòu)圖。 |
這就是一種不便,它使得系統(tǒng)的邏輯變得不必要的復(fù)雜,維護(hù)成本提高,復(fù)用率降低。
用一個(gè)范例說明,中國大陸的醫(yī)院便是一個(gè)子系統(tǒng),按照部門職能,這個(gè)系統(tǒng)可以劃分為掛號、門診、劃價(jià)、化驗(yàn)、收銀、取藥等。看病的病人要與這些部門打交道,就如同一個(gè)子系統(tǒng)的使用端與一個(gè)子系統(tǒng)的各個(gè)類型打交道一樣,不是一件容易的事情。
首先病人必須先掛號,然后門診。如果醫(yī)生要求化驗(yàn),病人必須首先劃價(jià),然后繳款,才能到化驗(yàn)部門做化驗(yàn)。化驗(yàn)后,再回到門診室,請見下面的對象圖。
![]() 圖5、描述病人在醫(yī)院里的體驗(yàn)。圖中的方框代表醫(yī)院。 |
解決這種不便的方法便是引進(jìn)Facade模式。仍然通過醫(yī)院的范例說明,可以設(shè)置一個(gè)接待員的位置,由接待員負(fù)責(zé)代為掛號、劃價(jià)、繳費(fèi)、取藥等。這個(gè)接待員就是Facade模式的體現(xiàn),病人只接觸接待員,由接待員負(fù)責(zé)與醫(yī)院的各個(gè)部門打交道,請見下面的對象圖。
![]() 圖6、描述經(jīng)過Facade模式的改裝后,病人在醫(yī)院里的體驗(yàn)。圖中的方框代表醫(yī)院。 |
Facade模式要求一個(gè)子系統(tǒng)的外部與其內(nèi)部的通訊必須通過一個(gè)統(tǒng)一的門面(Facade)對象進(jìn)行。Facade模式提供一個(gè)高等級的接口,使得子系統(tǒng)更易于使用。
使用了Facade模式之后,本章的第一個(gè)圖中所描述的一個(gè)子系統(tǒng)的使用端對象所面對的復(fù)雜關(guān)系就可以簡化為下面這個(gè)樣子。
![]() 圖7、Facade架構(gòu)模式的結(jié)構(gòu)圖 |
描述經(jīng)過Facade模式的改裝后,一個(gè)子系統(tǒng)的使用端與子系統(tǒng)的關(guān)系。圖中的大方框代表一個(gè)子系統(tǒng)。
就如同醫(yī)院的接待員一樣,F(xiàn)acade模式的門面類型將使用端與子系統(tǒng)的內(nèi)部復(fù)雜性分隔開,使得使用端只需要與門面對象打交道,而不需要與子系統(tǒng)內(nèi)部的很多對象打交道。
Mediator架構(gòu)模式
Mediator模式包裝了一系列對象相互作用的方式,使得這些對象不必互相明顯參照;從而使它們可以較松散地耦合。當(dāng)這些對象中的某些對象之間的相互作用發(fā)生改變時(shí),不會(huì)立即影響到其它的一些對象之間的相互作用;從而可以保證這些相互作用可以彼此獨(dú)立地變化。
在下面的示意圖中有大量的對象,這些對象既會(huì)影響別的對象,又會(huì)被別的對象所影響,因此常常叫做同事(Colleague)對象。這些同事對象通過彼此的相互作用形成系統(tǒng)的行為。從圖中可以看出,幾乎每一個(gè)對象都需要與其它的對象發(fā)生相互作用,而這種相互作用表現(xiàn)為一個(gè)對象與另一個(gè)對象的直接耦合。
![]() 圖8、這是一個(gè)過度耦合的系統(tǒng) |
通過引入調(diào)停者對象(Mediator),可以將系統(tǒng)的網(wǎng)狀結(jié)構(gòu)變成以中介者為中心的星形結(jié)構(gòu),如下圖所示。在這個(gè)星形結(jié)構(gòu)中,同事對象不再通過直接的聯(lián)系與另一個(gè)對象發(fā)生相互作用;相反地,它通過調(diào)停者對象與另一個(gè)對象發(fā)生相互作用。調(diào)停者對象的存在保證了對象結(jié)構(gòu)上的穩(wěn)定,也就是說,系統(tǒng)的結(jié)構(gòu)不會(huì)因?yàn)樾聦ο蟮囊朐斐纱罅康男薷墓ぷ鳌?
![]() 圖9、這是一個(gè)使用了Mediator架構(gòu)模式之后的結(jié)構(gòu)圖 |
比較傳統(tǒng)的設(shè)計(jì)方法,面向?qū)ο蟮募夹g(shù)可以更好地協(xié)助設(shè)計(jì)師管理更為復(fù)雜的系統(tǒng)。一個(gè)好的面向?qū)ο蟮脑O(shè)計(jì)可以使對象之間增加協(xié)作性(Collaboration),減少耦合度(Coupling)。一個(gè)深思熟慮的設(shè)計(jì)會(huì)把一個(gè)系統(tǒng)分解為一群相互協(xié)作的同事對象,然后給每一個(gè)同事對象以獨(dú)特的責(zé)任,恰當(dāng)?shù)呐渲盟鼈冎g的協(xié)作關(guān)系,使它們可以在一起工作。
在Mediator模式中,所有的成員對象都可以協(xié)調(diào)工作,但是又不直接相互管理。這些對象都與一個(gè)處于中心地位的調(diào)停者對象發(fā)生緊密的關(guān)系,由這個(gè)調(diào)停者對象進(jìn)行協(xié)調(diào)工作。這個(gè)協(xié)調(diào)者對象叫做調(diào)停者(Mediator),而調(diào)停者所協(xié)調(diào)的成員對象稱做同事(Colleague)對象。
在Colleague對象內(nèi)部發(fā)生的事件會(huì)影響到所有的同事,但是這種影響不是以直接管理的方式直接傳到其它的對象上的。記住在小組的成員增加時(shí),這樣的相互作用關(guān)系是以比指數(shù)更快的方式增加的。相反,這種影響僅僅直接影響到調(diào)停者對象,而調(diào)停者對象反過來會(huì)協(xié)調(diào)其它的同事,形成整個(gè)系統(tǒng)的行為。
如果小組的成員增加時(shí),調(diào)停者對象可能會(huì)面臨修改,而其它的同事則可以裝做不知道這個(gè)新的成員一樣,不必修改。反過來,如果小組的成員之一被從系統(tǒng)中刪除的話,調(diào)停者對象需要對此做出修改,而小組中其它的同事則不必改動(dòng)。
Interpreter架構(gòu)模式
給定一個(gè)語言之后,Interpreter模式可以定義出其文法的一種表示,并同時(shí)提供一個(gè)直譯器;使用端可以使用這個(gè)直譯器來解釋這個(gè)語言中的句子。
如果某一類型問題一再地發(fā)生的話,那么一個(gè)有意義的做法就是將此類型問題的各個(gè)實(shí)例表達(dá)為一個(gè)簡單語言中的語句。這樣就可以建造一個(gè)直譯器,通過解釋這些語句達(dá)到解決問題的目的。
例如,依照一個(gè)匹配模式搜尋字符串便是一個(gè)常見的問題。與其為每一個(gè)匹配模式建造一個(gè)特定的算法,不如建造一個(gè)一般性的算法處理各種常規(guī)表達(dá)式。當(dāng)接到一個(gè)指定的常規(guī)表達(dá)式時(shí),系統(tǒng)使用一個(gè)直譯器解釋這個(gè)常規(guī)表達(dá)式,從而對字符串進(jìn)行匹配。
再比如VBA(Visual Basic for Applications)就不僅僅出現(xiàn)在微軟的Office系列軟件中,并且可以供第三廠家出產(chǎn)的軟件嵌入使用;Crystal Reports報(bào)表生成軟件也包括了一個(gè)便于使用的宏語言,使用戶可以執(zhí)行較為復(fù)雜的命令操作。一般而言,將VBA或者其它的語言軟件嵌入到自己的軟件產(chǎn)品中,可以使產(chǎn)品定制化(Customization)能力大大增強(qiáng),但是這些宏語言引擎往往都很昂貴。
現(xiàn)在要介紹的Interpreter模式將描述怎樣在有了一個(gè)簡單的文法后,使用模式設(shè)計(jì)解釋這些語句。熟悉了這個(gè)模式以后,一個(gè)沒有接收過形式語言和編譯器的正規(guī)訓(xùn)練的設(shè)計(jì)師也可以自行設(shè)計(jì)一個(gè)簡單的直譯器,以便為使用端提供一個(gè)簡單語言,或者在系統(tǒng)內(nèi)部使用一個(gè)簡單語言描述一個(gè)合適的問題。
語言、直譯器和剖析器
Interpreter模式只描述直譯器是怎樣工作的,并不指明怎樣在執(zhí)行時(shí)創(chuàng)建新的直譯器。雖然廣義地講直譯器不一定要有一個(gè)剖析器(Parser),但是使用剖析器仍然是最常見的建立直譯器的辦法。一個(gè)剖析器可以從一個(gè)檔或命令行讀入文字性命令,并創(chuàng)建直譯器。
剖析器是一種能夠識別文字并將文字按照一定規(guī)則進(jìn)行分解以便進(jìn)一步處理的對象。剖析器能夠識別的字符串叫做語言。通常建立的小型計(jì)算機(jī)語言是與環(huán)境無關(guān)的語言,也就是遵循一定的文法的文字模式,所謂文法,便是決定怎樣將語言的元素組合起來的規(guī)則的集合。剖析器便是根據(jù)組合規(guī)則將字符串分解的。
抽象地講,語言并不一定是以字符串的形式表達(dá)的。在Interpreter模式里面所提到的語言是指任何直譯器對象能夠解釋的任何組合。在Interpreter模式中,需要定義一個(gè)代表文法的命令類型的等級結(jié)構(gòu),也就是一系列的組合規(guī)則;每一個(gè)命令對象都有一個(gè)解釋方法,代表對命令對象的解釋。
命令對象的等級結(jié)構(gòu)中的對象的任何排列組合都是一個(gè)語言,而剖析器的工作便是將一個(gè)文字性語言翻譯成為等效的直譯器語言。因此,直譯器往往需要剖析器。
認(rèn)識Jack嗎?
剖析器生成器(Parser Generator),常常稱為編譯器的編譯器(Compiler Complier)。Sun Microsystem提供一個(gè)專為Java程序員發(fā)明的強(qiáng)大的剖析器生成器,最初叫做Jack,后來改名為JavaCC。
要使用JavaCC,必須使用它提供的腳本語言編寫一個(gè)腳本,然后執(zhí)行JavaCC生成Java源代碼。這生成的源代碼就是所需的剖析器。現(xiàn)在Sun已經(jīng)不再負(fù)責(zé)JavaCC的研發(fā),對JavaCC感興趣的讀者可以從http://www.experimentalstuff.com/Technologies/JavaCC得到免費(fèi)的JavaCC和相關(guān)數(shù)據(jù)。
JavaCC最早命名為Jack是為了與一個(gè)早就廣泛使用的剖析器生成器YACC諧音。如果讀者已經(jīng)熟悉了YACC,可以使用YACC達(dá)到同樣的目的;只是相比之下JavaCC更容易得到Java程序員的喜愛。
(http://www.fanqiang.com)
|
|
歡迎大家訪問我的個(gè)人網(wǎng)站 萌萌的IT人
posted on 2006-04-10 13:27 見酒就暈 閱讀(151) 評論(0) 編輯 收藏 所屬分類: PATTERN