1. 程式人生 > >架構設計的方法學 專訪架構師周愛民:談企業軟體架構設計 C++之設計模式實現程式碼

架構設計的方法學 專訪架構師周愛民:談企業軟體架構設計 C++之設計模式實現程式碼

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow

也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!

               

什麼是架構

前言:軟體設計師中有一些技術水平較高、經驗較為豐富的人,他們需要承擔軟體系統的架構設計,也就是需要設計系統的元件如何劃分、元件之間如何發生相互作用,以及系統中邏輯的、物理的、系統的重要決定的作出。在很多公司中,架構師不是一個專門的和正式的職務。通常在一個開發小組中,最有經驗的程式設計師會負責一些架構方面的工作。在一個部門中,最有經驗的專案經理會負責一些架構方面的工作。但是,越來越多的公司體認到架構工作的重要性。

  什麼是軟體系統的架構(Architecture)?一般而言,架構有兩個要素:

  ·它是一個軟體系統從整體到部分的最高層次的劃分。

  一個系統通常是由元件組成的,而這些元件如何形成、相互之間如何發生作用,則是關於這個系統本身結構的重要資訊。

  詳細地說,就是要包括架構元件(Architecture Component)、聯結器(Connector)、任務流(Task-flow)。所謂架構元素,也就是組成系統的核心"磚瓦",而聯結器則描述這些元件之間通訊的路徑、通訊的機制、通訊的預期結果,任務流則描述系統如何使用這些元件和聯結器完成某一項需求。

  ·建造一個系統所作出的最高層次的、以後難以更改的,商業的和技術的決定。

  在建造一個系統之前會有很多的重要決定需要事先作出,而一旦系統開始進行詳細設計甚至建造,這些決定就很難更改甚至無法更改。顯然,這樣的決定必定是有關係統設計成敗的最重要決定,必須經過非常慎重的研究和考察。

  計算機軟體的歷史開始於五十年代,歷史非常短暫,而相比之下建築工程則從石器時代就開始了,人類在幾千年的建築設計實踐中積累了大量的經驗和教訓。建築設計基本上包含兩點,一是建築風格,二是建築模式。獨特的建築風格和恰當選擇的建築模式,可以使一個獨一無二。

  下面的照片顯示了中美洲古代瑪雅建築,Chichen-Itza大金字塔,九個巨大的石級堆壘而上,九十一級臺階(象徵著四季的天數)奪路而出,塔頂的神殿聳入雲天。所有的數字都如日曆般嚴謹,風格雄渾。難以想象這是石器時代的建築物。



圖1、位於墨西哥Chichen-Itza(在瑪雅語中chi意為嘴chen意為井)的古瑪雅建築。(攝影:作者)

  軟體與人類的關係是架構師必須面對的核心問題,也是自從軟體進入歷史舞臺之後就出現的問題。與此類似地,自從有了建築以來,建築與人類的關係就一直是建築設計師必須面對的核心問題。英國首相丘吉爾說,我們構造建築物,然後建築物構造我們(We shape our buildings, and afterwards our buildings shape us)。英國下議院的會議廳較狹窄,無法使所有的下議院議員面向同一個方向入座,而必須分成兩側入座。丘吉爾認為,議員們入座的時候自然會選擇與自己政見相同的人同時入座,而這就是英國政黨制的起源。Party這個詞的原意就是"方"、"面"。政黨起源的關鍵就是建築物對人的影響。

  在軟體設計界曾經有很多人認為功能是最為重要的,形式必須服從功能。與此類似地,在建築學界,現代主義建築流派的開創人之一Louis Sullivan也認為形式應當服從於功能(Forms follows function)。

  幾乎所有的軟體設計理念都可以在浩如煙海的建築學歷史中找到更為遙遠的歷史迴響。最為著名的,當然就是模式理論和XP理論。

  架構的目標是什麼

  正如同軟體本身有其要達到的目標一樣,架構設計要達到的目標是什麼呢?一般而言,軟體架構設計要達到如下的目標:

  ·可靠性(Reliable)。軟體系統對於使用者的商業經營和管理來說極為重要,因此軟體系統必須非常可靠。

  ·安全行(Secure)。軟體系統所承擔的交易的商業價值極高,系統的安全性非常重要。

  ·可擴充套件性(Scalable)。軟體必須能夠在使用者的使用率、使用者的數目增加很快的情況下,保持合理的效能。只有這樣,才能適應使用者的市場擴充套件得可能性。

  ·可定製化(Customizable)。同樣的一套軟體,可以根據客戶群的不同和市場需求的變化進行調整。

  ·可擴充套件性(Extensible)。在新技術出現的時候,一個軟體系統應當允許匯入新技術,從而對現有系統進行功能和效能的擴充套件

  ·可維護性(Maintainable)。軟體系統的維護包括兩方面,一是排除現有的錯誤,二是將新的軟體需求反映到現有系統中去。一個易於維護的系統可以有效地降低技術支援的花費

  ·客戶體驗(Customer Experience)。軟體系統必須易於使用。

  ·市場時機(Time to Market)。軟體使用者要面臨同業競爭,軟體提供商也要面臨同業競爭。以最快的速度爭奪市場先機非常重要。

  架構的種類

  根據我們關注的角度不同,可以將架構分成三種:

  ·邏輯架構、軟體系統中元件之間的關係,比如使用者介面,資料庫,外部系統介面,商業邏輯元件,等等。

  比如下面就是筆者親身經歷過的一個軟體系統的邏輯架構圖

 

圖2、一個邏輯架構的例子

  從上面這張圖中可以看出,此係統被劃分成三個邏輯層次,即表象層次,商業層次和資料持久層次。每一個層次都含有多個邏輯元件。比如WEB伺服器層次中有HTML服務元件、Session服務元件、安全服務元件、系統管理元件等。

  ·物理架構、軟體元件是怎樣放到硬體上的。

  比如下面這張物理架構圖描述了一個分佈於北京和上海的分散式系統的物理架構,圖中所有的元件都是物理裝置,包括網路分流器、代理伺服器、WEB伺服器、應用伺服器、報表伺服器、整合伺服器、儲存伺服器、主機等等。

 

圖3、一個物理架構的例子

  ·系統架構、系統的非功能性特徵,如可擴充套件性、可靠性、強壯性、靈活性、效能等。

  系統架構的設計要求架構師具備軟體和硬體的功能和效能的過硬知識,這一工作無疑是架構設計工作中最為困難的工作。

  此外,從每一個角度上看,都可以看到架構的兩要素:元件劃分和設計決定。

  首先,一個軟體系統中的元件首先是邏輯元件。這些邏輯元件如何放到硬體上,以及這些元件如何為整個系統的可擴充套件性、可靠性、強壯性、靈活性、效能等做出貢獻,是非常重要的資訊。

  其次,進行軟體設計需要做出的決定中,必然會包括邏輯結構、物理結構,以及它們如何影響到系統的所有非功能性特徵。這些決定中會有很多是一旦作出,就很難更改的。

  根據作者的經驗,一個基於資料庫的系統架構,有多少個數據表,就會有多少頁的架構設計文件。比如一箇中等的資料庫應用系統通常含有一百個左右的資料表,這樣的一個系統設計通常需要有一百頁左右的架構設計文件。

  架構師

  軟體設計師中有一些技術水平較高、經驗較為豐富的人,他們需要承擔軟體系統的架構設計,也就是需要設計系統的元件如何劃分、元件之間如何發生相互作用,以及系統中邏輯的、物理的、系統的重要決定的作出。

  這樣的人就是所謂的架構師(Architect)。在很多公司中,架構師不是一個專門的和正式的職務。通常在一個開發小組中,最有經驗的程式設計師會負責一些架構方面的工作。在一個部門中,最有經驗的專案經理會負責一些架構方面的工作。

  但是,越來越多的公司體認到架構工作的重要性,並且在不同的組織層次上設定專門的架構師位置,由他們負責不同層次上的邏輯架構、物理架構、系統架構的設計、配置、維護等工作。

軟體的架構設計

好的開始相當於成功一半

開始之初的架構設計決定著軟體產品的生死存亡。“好的開始相當於成功一半”。

開始的架構設計也是最難的,需要調研同類產品的情況以及技術特徵,瞭解當前世界上對這種產品所能提供的理論支援和技術平臺支援。再結合自己專案的特點(需要透徹的系統分析),才能逐步形成自己專案的架構藍圖。

比如要開發網站引擎系統,就從Yahoo的個人主頁生成工具到虛擬主機商提供的網站自動生成系統,以及IBM Webphere Portal的特點和侷限 從而從架構設計角度定立自己產品的位置。

好的設計肯定需要經過反覆修改,從簡單到複雜的迴圈測試是保證設計正確的一個好辦法

由於在開始選擇了正確的方向,後來專案的實現過程也驗證了這種選擇,但在一些架構設計的細部方面,還需要對方案進行修改,屬於那種螺旋上升的方式,顯然這是通過測試第一的思想和XP工程方法來實現的。

如果我們開始的架構設計在技術平臺定位具有一定的世界先進水平,那麼,專案開發實際有一半相當於做實驗,是研發,存在相當的技術風險。

因此,一開始我們不可能將每個需求都實現,而是採取一種簡單完成架構流程的辦法,使用最簡單的需求將整個架構都簡單的完成一遍(加入人工干預),以檢驗各個技術環節是否能協調配合工作(非常優秀先進的兩種技術有時無法在一起工作),同時也可以探知技術的深淺,掌握專案中的技術難易點。這個過程完成後,我們就對設計方案做出上面的重大修改,豐富完善了設計方案。

設計模式是支撐架構的重要元件

架構設計也類似一種工作流,它是動態的,這點不象建築設計那樣,一開始就能完全確定,架構設計伴隨著整個專案的進行過程之中,有兩種具體操作保證架構設計的正確完成,那就是設計模式(靜態)和工程專案方法(RUP或XP 動態的)。

設計模式是支撐架構的一種重要元件,這與建築有很相象的地方,一個建築物建立設計需要建築架構設計,在具體施工中,有很多建築方面的規則和模式。

我們從J2EE藍圖模式分類http://java.sun.com/blueprints/patterns/catalog.html中就可以很清楚的看到J2EE這樣一個框架軟體的架構與設計模式的關係。

架構設計是骨架,設計模式就是肉

這樣,一個比較豐富的設計方案可以交由程式設計師進一步完成了,載輔助以適當的工程方法,這樣就可保證專案的架構設計能正確快速的完成。

時刻牢記架構設計的目標

由於架構設計是在動態中完成的,因此在把握架構設計的目標上就很重要,因此在整個專案過程中,甚至每一步我們都必須牢記我們架構設計的總體目標,可以概括下面幾點:

1. 最大化的重用:這個重用包括元件重用 和設計模式使用等多個方面。

比如,我們專案中有使用者註冊和使用者許可權系統驗證,這其實是個通用課題,每個專案只是有其內容和一些細微的差別,如果我們之前有這方面成功研發經驗,可以直接重用,如果沒有,那麼我們就要進行這個子專案的研發,在研發過程中,不能僅僅看到這個專案的需求,也要以架構的概念去完成這個可以稱為元件的子專案。

2. 儘可能的簡單明瞭:我們解決問題的總方向是將複雜問題簡單化,其實這也是中介軟體或多層體系技術的根本目標。但是在具體實施設計過程中,我們可能會將簡單問題複雜化,特別是設計模式的運用上很容易範這個錯誤,因此如何儘可能的做到設計的簡單明瞭是不容易的。

我認為落實到每個類的具體實現上要真正能體現系統事物的本質特徵,因為事物的本質特徵只有一個,你的程式碼越接近它,表示你的設計就是簡單明瞭,越簡單明瞭,你的系統就越可靠。更多情況是,一個類並不能反應事物本質,需要多個類的組合協調,那麼能夠正確使用合適的設計模式就稱為重中之重。

我們看一個具備好的架構設計的系統程式碼時,基本看到的都是設計模式,寵物店(pet store)就是這樣的例子。或者可以這樣說,一個好的架構設計基本是由簡單明瞭的多個設計模式完成的。

3. 最靈活的拓展性:架構設計要具備靈活性 拓展性,這樣,使用者可以在你的架構上進行二次開發或更加具體的開發。

要具備靈活的拓展性,就要站在理論的高度去進行架構設計,比如現在工作流概念逐步流行,因為我們具體很多實踐專案中都有工作流的影子,工作流中有一個樹形結構許可權設定的概念就對很多領域比較通用。

樹形結構是組織資訊的基本形式,我們現在看到的網站或者ERP前臺都是以樹形選單來組織功能的,那麼我們在進行架構設計時,就可以將樹形結構和功能分開設計,他們之間聯絡可以通過樹形結構的節點link在一起,就象我們可以在聖誕樹的樹枝上掛各種小禮品一樣,這些小禮品就是我們要實現的各種功能。

有了這個概念,通常比較難實現的使用者級別許可權控制也有了思路,將具體使用者或組也是和樹形結構的節點link在一起,這樣就間接實現了使用者對相應功能的許可權控制,有了這樣的基本設計方案的架構無疑具備很靈活的拓展性。 

如何設計架構?

2007-07-19 11:11 來源: 作者: 網友評論 0 條 瀏覽次數 26

Part 1 層

    層(layer)這個概念在計算機領域是非常了不得的一個概念。計算機本身就體現了一種層的概念:系統呼叫層、裝置驅動層、作業系統層、CPU指令集。每個層都負責自己的職責。網路同樣也是層的概念,最著名的TCP/IP的七層協議。

    層到了軟體領域也一樣好用。為什麼呢?我們看看使用層技術有什麼好處:

    ● 你使用層,但是不需要去了解層的實現細節。
    ● 可以使用另一種技術來改變基礎的層,而不會影響上面的層的應用。
    ● 可以減少不同層之間的依賴。
    ● 容易制定出層標準。
    ● 底下的層可以用來建立頂上的層的多項服務。

    當然,層也有弱點:

    ● 層不可能封裝所有的功能,一旦有功能變動,勢必要波及所有的層。
    ● 效率降低。

當然,層最難的一個問題還是各個層都有些什麼,以及要承擔何種責任。

典型的三層結構

    三層結構估計大家都很熟悉了。就是表示(presentation)層, 領域(domain)層, 以及基礎架構(infrastructure)層。

    表示層邏輯主要處理使用者和軟體的互動。現在最流行的莫過於視窗圖形介面(wimp)和基於html的介面了。表示層的主要職責就是為使用者提供資訊,以及把使用者的指令翻譯。傳送給業務層和基礎架構層。

    基礎架構層邏輯包括處理和其他系統的通訊,代表系統執行任務。例如資料庫系統互動,和其他應用系統的互動等。大多數的資訊系統,這個層的最大的邏輯就是儲存持久資料。

    還有一個就是領域層邏輯,有時也被叫做業務邏輯。它包括輸入和儲存資料的計算。驗證表示層來的資料,根據表示層的指令指派一個基礎架構層邏輯。

    領域邏輯中,人們總是搞不清楚什麼事領域邏輯,什麼是其它邏輯。例如,一個銷售系統中有這樣一個邏輯:如果本月銷售量比上個月增長10%,就要用紅色標記。要實現這個功能,你可能會把邏輯放在表示層中,比較兩個月的數字,如果超出10%,就標記為紅色。

    這樣做,你就把領域邏輯放到了表示層中了。要分離這兩個層,你應該現在領域層中提供一個方法,用來比較銷售數字的增長。這個方法比較兩個月的數字,並返回boolean型別。表示層則簡單的呼叫該方法,如果返回true,則標記為紅色。

例子

    層技術不存在說永恆的技巧。如何使用都要看具體的情況才能夠決定,下面我就列出了三個例子:

    例子1:一個電子商務系統。要求能夠同時處理大量使用者的請求,使用者的範圍遍及全球,而且數字還在不斷增長。但是領域邏輯很簡單,無非是訂單的處理,以及和庫存系統的連線部分。這就要求我們1、表示層要友好,能夠適應最廣泛的使用者,因此採用html技術;2、支援分散式的處理,以勝任同時幾千的訪問;3、考慮未來的升級。

    例子2:一個租借系統。系統的使用者少的多,但是領域邏輯很複雜。這就要求我們製作一個領域邏輯非常複雜的系統,另外,還要給他們的使用者提供一個方便的輸入介面。這樣,wimp是一個不錯的選擇。

    例子3:簡單的系統。非常簡單,使用者少、邏輯少。但是也不是沒有問題,簡單意味著要快速交付,並且還要充分考慮日後的升級。因為需求在不斷的增加之中。

何時分層

    這樣的三個例子,就要求我們不能夠一概而論的解決問題,而是應該針對問題的具體情況制定具體的解決方法。這三個例子比較典型。

    第二個例子中,可能需要嚴格的分成三個層次,而且可能還要加上另外的中介(mediating)層。例3則不需要,如果你要做的僅是檢視資料,那僅需要幾個server頁面來放置所有的邏輯就可以了。

    我一般會把表示層和領域層/基礎架構層分開。除非領域層/基礎架構層非常的簡單,而我又可以使用工具來輕易的繫結這些層。這種兩層架構的最好的例子就是在VB、PB的環境中,很容易就可以構建出一個基於SQL資料庫的windows介面的系統。這樣的表示層和基礎架構層非常的一致,但是一旦驗證和計算變得複雜起來,這種方式就存在先天缺陷了。

    很多時候,領域層和基礎架構層看起來非常類似,這時候,其實是可以把它們放在一起的。可是,當領域層的業務邏輯和基礎架構層的組織方式開始不同的時候,你就需要分開二者。

更多的層模式

    三層的架構是最為通用的,尤其是對IS系統。其它的架構也有,但是並不適用於任何情況。

    第一種是Brown model [Brown et al]。它有五個層:表示層(Presentation),控制/中介層(Controller/Mediator),領域層(Domain), 資料對映層(Data Mapping), 和資料來源層(Data Source)。它其實就是在三層架構種增加了兩個中間層。控制/中介層位於表示層和領域層之間,資料對映層位於領域層和基礎架構層之間。

    表示層和領域層的中介層,我們通常稱之為表示-領域中介層,是一個常用的分層方法,通常針對一些非可視的控制元件。例如為特定的表示層組織資訊格式,在不同的視窗間導航,處理交易邊界,提供Server的facade介面(具體實現原理見設計模式)。最大的危險就是,一些領域邏輯被放到這個層裡,影響到其它的表示層。

    我常常發現把行為分配給表示層是有好處的。這可以簡化問題。但表示層模型會比較複雜,所以,把這些行為放到非視覺化的物件中,並提取出一個表示-領域中介層還是值得的。

    Brown ISA
    表示層 表示層
   控制/中介層 表示-領域中介層
    領域層 領域層
    資料對映層 資料庫互動模式中的Database Mapper
    資料來源層 基礎架構層

    領域層和基礎架構層之間的中介層屬於本書中提到的Database Mapper模式,是三種領域層到資料連線的辦法之一。和表示-領域中介層一眼,有時候有用,但不是所有時候都有用。

    還有一個好的分層架構是J2EE的架構,這方面的討論可以見『J2EE核心模式』一書。他的分層是客戶層(Client),表示層(Presentation),業務層(Business ),整合層(Integration),資源層(Resource)。差別如下圖:

    J2EE核心 ISA
    客戶層 執行在客戶機上的表示層
   表示層 執行在伺服器上的表示層
    業務層 領域層
    整合層 基礎架構層
    資源層 基礎架構層通訊的外部資料

    微軟的DNA架構定義了三個層:表示層(presentation),業務層(business),和資料儲存層(data access),這和我的架構相似,但是在資料的傳遞方式上還有很大的不同。在微軟的DNA中,各層的操作都基於資料儲存層傳出的SQL查詢結果集。這樣的話,實際上是增加了表示層和業務層同資料儲存層之間的耦合度。

    DNA的記錄集在層之間的動作類似於Data Transfer Object。
    


Part 2 組織領域邏輯

    要組織基於層的系統,首要的是如何組織領域邏輯。領域邏輯的組織有好幾種模式。但其中最重要的莫過於兩種方法:Transation Script和Domain Model。選定了其中的一種,其它的都容易決定。不過,這兩者之間並沒有一條明顯的分界線。所以如何選取也是門大學問。一般來說,我們認為領域邏輯比較複雜的系統可以採用Domain Model。

    Transation Script就是對錶示層使用者輸入的處理程式。包括驗證和計算,儲存,呼叫其它系統的操作,把資料回傳給表示層。使用者的一個動作表示一個程式,這個程式可以是script,也可以是transation,也可以是幾個子程式。在例子1中,檢驗,在購物車中增加一本書,顯示遞送狀態,都可以是一個Transation Script。

    Domain Model是要建立對應領域名詞的模型,例如例1中的書、購物車等。檢驗、計算等處理都放到領域模型中。

    Transation Script屬於結構性思維,Domain Model屬於OO思維。Domain Model比較難使用,一旦習慣,你能夠組織更復雜的邏輯,你的思想會更OO。到時候,即使是小的系統,你也會自然的使用Domain Model了。

    但如何抉擇呢?如果邏輯複雜,那肯定用Domain Model:如果只需要存取資料庫,那Transation Script會好一些。但是需求是在不斷進化的,你很難保證以後的需求還會如此簡單。如果你的團隊不善於使用Domain Model,那你需要權衡一下投入產出比。另外,即使是Transation Script,也可以做到把邏輯和基礎架構分開,你可以使用Gateway。

    對例2,毫無疑問要使用Domain Model。對例1就需要權衡了。而對於例3,你很難說它將來會不會像例2那樣,你現在可以使用Transation Script,但未來你可能要使用Domain Model。所以說,架構的決策是至關緊要的。

    除了這兩種模式,還有其它中庸的模式。Use Case Controller就是處於兩者之間。只有和單個的用例相關的業務邏輯才放到物件中。所以大致上他們還是在使用Transation Script,而Domain Model只是Database Gateway的一組集合而已。我不太用這種模式。

    Table Module是另一箇中庸模式。很多的GUI環境依託於SQL查詢的返回結果。你可以建立記憶體中的物件,來把GUI和資料庫分開來。為每個表寫一個模組,因此每一行都需要關鍵字變數來識別每一個例項。

    Table Module適用於很多的元件構建於一個通用關係型資料庫之上,而且領域邏輯不太複雜的情況。Microsoft COM 環境,以及它的帶ADO.NET的.NET環境都適合使用這種模式。而對於Java,就不太適用了。

    領域邏輯的一個問題是領域物件非常的臃腫。因為物件的行為太多了,類也就太大了。它必須是一個超集。這就要考慮哪些行為是通用的,哪些不是,可以由其它的類來處理,可能是Use Case Controller,也可能是表示層。

    還有一個問題,複製。他會導致複雜和不一致。這比臃腫的危害更大。所以,寧可臃腫,也不要複製。等到臃腫為害時再處理它吧。

選擇一個地方執行領域邏輯

    我們的精力集中在邏輯層上。領域邏輯要麼執行在Client上,要麼執行在Server上。

    比較簡單的做法是全部集中在Server上。這樣你需要使用html的前端以及web server。這樣做的好處是升級和維護都非常的簡單,你也不用考慮桌面平臺和Server的同步問題,也不用考慮桌面平臺的其它軟體的相容問題。

    執行在Client適合於要求快速反應和沒有聯網的情況。在Server端的邏輯,使用者的一個再小的請求,也需要資訊從Client到Server繞一圈。反應的速度必然慢。再說,網路的覆蓋程度也不是說達到了100%。

    對於各個層來說,又是怎麼樣的呢?

    基礎架構層:一般都是在Server啦,不過有時候也會把資料複製到合適的高效能桌面機,但這是就要考慮同步的問題了。

    表示層在何處執行取決於使用者介面的設計。一個Windows介面只能在Client執行。而一個Web介面就是在Server執行。也有特別的例子,在桌面機上執行web server的,例如X Server。但這種情況少的多。

    在例1中,沒有更多的選擇了,只能選在Server端。因此你的每一個bit都會繞一個大圈子。為了提高效率,儘量使用一些純html指令碼。

    人們選用Windows介面的原因主要就是需要執行一些非常複雜的任務,需要一個合適的應用程式,而web GUI則無法勝任。這就是例2的做法。不過,人們應該會漸漸適應web GUI,而web GUI的功能也會越來越強大。

    剩下的是領域邏輯。你可以全部放在Server,也可以全部放在Client,或是兩邊都放。

    如果是在Client端,你可以考慮全部邏輯都放在Client端,這樣至少保證所有的邏輯都在一個地方。而把web server移至Client,是可以解決沒有聯網的問題,但對反應時間不會有多大的幫助。你還是可以把邏輯和表示層分離開來。當然,你需要額外的升級和維護的工作。

    在Client和Server端都具有邏輯並不是一個好的處理辦法。但是對於那些僅有一些領域邏輯的情況是適用的。有一個小竅門,把那些和系統的其它部分沒有聯絡的邏輯封裝起來。

領域邏輯的介面

    你的Server上有一些領域邏輯,要和Client通訊,你應該有什麼樣的介面呢?要麼是一個http介面,要麼是一個OO介面。

    http介面適用於web browser,就是說你要選擇一個html的表示層。最近的新技術就是web service,通過基於http、特別是XML進行通訊。XML有幾個好處:通訊量大,結構好,僅需一次的迴路。這樣遠端呼叫的的開銷就小了。同時,XML還是一個標準,支援平臺異構。XML又是基於文字的,能夠通過防火牆。

    雖然XML有那麼多的好處,不過一個OO的介面還是有它的價值的。hhtp的介面不明顯,不容易看清楚資料是如何處理的。而OO的介面的方法帶有變數和名字,容易看出處理的過程。當然,它無法通過防火牆,但可以提供安全和事務之類的控制。

    最好的還是取二者所長。OO介面在下,http介面在上。但這樣做就會使得實現機制非常的複雜。

 

Part 3 組織web Server

    很多使用html方式的人,並不能真正理解這種方式的優點。我們有各種各樣好用的工具,但是卻搞到讓程式難以維護。

    在web server上組織程式的方式大致可以分為兩種:指令碼和server page。

    指令碼方式就是一個程式,用函式和方法來處理http呼叫。例如CGI指令碼和java servlet。它和普通的程式並沒有什麼兩樣。它從web頁面上獲得html string形態的資料,有時候還要做一些表示式匹配,這正是perl能夠成為CGI指令碼的常用語言的原因。而java servelet則是把這種分析留給程式設計師,但它允許程式設計師通過關鍵字介面來訪問資訊,這樣就會少一些表示式的判斷。這種格式的web server輸出是另一種html string,稱為response,可以通過流資料來操作。

    糟糕的是流資料是非常麻煩的,因此就導致了server page的產生,例如PHP,ASP,JSP。

    server page的方式適合迴應(response)的處理比較簡單的情況。例如“顯示歌曲的明細”,但是你的決策取決於輸入的時候,就會比較雜亂。例如“通俗和搖滾的顯示格式不同”。

    腳步擅長於處理使用者互動,server page擅長於處理格式化迴應資訊。所以很自然的就會採用指令碼處理請求的互動,使用server page處理迴應的格式化。這其實就是著名的MVC(Model View Controller)模式中的view/controller的處理。

web server端的MVC工作流程示意圖


    應用Model View Controller模式首要的一點就是模型要和web服務完全分離開來。使用Transaction Script或Domain Model模式來封裝處理流程。

    接下來,我們就把剩餘的模式歸入兩類模式中:屬於Controller的模式,以及屬於View的模式。

View模式

    View這邊有三種模式:Transform View,Template View和Two Step View。Transform View和Template View的處理只有一步,將領域資料轉換為html。Two Step View要經過兩步的處理,第一步把領域資料轉換為邏輯表示形式,第二步把邏輯表示轉換為html。

    兩步處理的好處是可以將邏輯集中於一處,如果只有一步,變化發生時,你就需要修改每一個螢幕。但這需要你有一個很好的邏輯螢幕結構。如果一個web應用有很多的前端使用者時,兩步處理就特別的好用。例如航空訂票系統。使用不同的第二步處理,就可以獲得不同的邏輯螢幕。

    使用單步方法有兩個可選的模式:Template View,Transform View。Template View其時就是把程式碼嵌入到html頁面中,就像現在的server page技術,如ASP,PHP,JSP。這種模式靈活,強大,但顯得雜亂無章。如果你能夠把邏輯程式邏輯在頁面結構之外進行很好的組織,這種模式還是有它的優點的。

    Transform View使用翻譯方式。例如XSLT。如果你的領域資料是用XML處理的,那這種模式就特別的好用。

Controller模式

    Controller有兩種模式。一般我們會根據動作來決定一項控制。動作可能是一個按鈕或連結。所這種模式就是Action Controller模式。

    Front Controller更進一步,它把http請求的處理和處理邏輯分離開來。一般是隻有一個web handle來處理所有的請求。你的所有的http請求的處理都由一個物件來負責。你改變動作結構的影響就會降到最小



架構設計的方法學

約公元前25年,古羅馬建築師維特魯威說:“理想的建築師應該既是文學家又是數字家,他還應通曉歷史,熱衷於哲學研究,精通音樂,懂得醫藥知識,具有法學造詣,深諳天文學及天文計算。”(好難哪,軟體構架設計師的要求呢?大家好好想想吧。)
  本文目錄
  一、與構架有關的幾個基本概念;
  二、構架設計應考慮的因素概攬;
  三、程式的執行時結構方面的考慮;
  四、原始碼的組織結構方面的考慮;
  五、寫系統構架設計文件應考慮的問題
  六、結語
  一、與構架有關的幾個基本概念:
  1、模組(module):一組完成指定功能的語句,包括:輸入、輸出、邏輯處理功能、內部資訊、執行環境(與功能對應但不是一對一關係)。
  2、元件(component):系統中相當重要的、幾乎是獨立的可替換部分,它在明確定義的構架環境中實現確切的功能。
  3、模式(pattern):指經過驗證,至少適用於一種實用環境(更多時候是好幾種環境)的解決方案模板(用於結構和行為。在 UML中:模式由引數化的協作來表示,但 UML 不直接對模式的其他方面(如使用結果列表、使用示例等,它們可由文字來表示)進行建模。存在各種範圍和抽象程度的模式,例如,構架模式、分析模式、設計模式和程式碼模式或實施模式。模式將可以幫助我們抓住重點。構架也是存在模式的。比如,對於系統結構設計,我們使用層模式;對於分散式系統,我們使用代理模式(通過使用代理來替代實際的物件,使程式能夠控制對該物件的訪問);對於互動系統,我們使用MVC(M模型(物件)/V檢視(輸出管理)/C控制器(輸入處理))模式。模式是針對特定問題的解,因此,我們也可以針對需求的特點採用相應的模式來設計構架。
  4、構架模式(architectural pattern):表示軟體系統的基本結構組織方案。它提供了一組預定義的子系統、指定它們的職責,並且包括用於組織其間關係的規則和指導。
  5、層(layer):對模型中同一抽象層次上的包進行分組的一種特定方式。通過分層,從邏輯上將子系統劃分成許多集合,而層間關係的形成要遵循一定的規則。通過分層,可以限制子系統間的依賴關係,使系統以更鬆散的方式耦合,從而更易於維護。(層是對構架的橫向劃分,分割槽是對構架的縱向劃分)。
  6、系統分層的幾種常用方法:
  1) 常用三層服務:使用者層、業務邏輯層、資料層;
  2) 多層結構的技術組成模型:表現層、中間層、資料層;
  3) 網路系統常用三層結構:核心層、匯聚層和接入層;
  4) RUP典型分層方法:應用層、專業業務層、中介軟體層、系統軟體層;
  5) 基於Java的B/S模式系統結構:瀏覽器端、伺服器端、請求接收層、請求處理層;
  6) 某六層結構:功能層(使用者介面)、模組層、組裝層(軟體匯流排)、服務層(資料處理)、資料層、核心層;
  7、構架(Architecture,願意為建築學設計和建築物建造的藝術與科學): 在RUP中的定義:軟體系統的構架(在某一給定點)是指系統重要構件的組織或結構,這些重要構件通過介面與不斷減小的構件與介面所組成的構件進行互動;《軟體構架實踐》中的定義:某個軟體或者計算系統的軟體構架即組成該系統的一個或者多個結構,他們組成軟體的各個部分,形成這些元件的外部可見屬性及相互間的聯絡;IEEE 1471-2000中的定義:the fundamental organization of a system emboided in its components,their relationships to each other,and to the enviroment and the principles guiding its design and evolution,構架是系統在其所處環境中的最高層次的概念。軟體系統的構架是通過介面互動的重要構件(在特定時間點)的組織或結構,這些構件又由一些更小的構件和介面組成。(“構架”可以作為名詞,也可作為動詞,作為動詞的“構架”相當於“構架設計”)
  8、構架的描述方式:“4+1”檢視(用例檢視、設計檢視、實現檢視、過程檢視、配置檢視)是一個被廣為使用的構架描述的模型;RUP過程的構架描述模板在“4+1”檢視的基礎上增加了可選的資料檢視(從永久性資料儲存方面來對系統進行說明);HP公司的軟體描述模板也是基於“4+1”檢視。
  9、結構:軟體構架是多種結構的體現,結構是系統構架從不同角度觀察所產生的檢視。就像建築物的結構會隨著觀察動機和出發點的不同而有多種含義一樣,軟體構架也表現為多種結構。常見的軟體結構有:模組結構、邏輯或概念結構、程序或協調結構、物理結構、使用結構、呼叫結構、資料流、控制流、類結構等等。
  二、構架設計應考慮的因素概攬:
  模組構架設計可以從程式的執行時結構和原始碼的組織結構方面考慮。
  1、程式的執行時結構方面的考慮:
  1) 需求的符合性:正確性、完整性;功能性需求、非功能性需求;
  2) 總體效能(記憶體管理、資料庫組織和內容、非資料庫資訊、任務並行性、網路多人操作、關鍵演算法、與網路、硬體和其他系統介面對效能的影響);
  3) 執行可管理性:便於控制系統執行、監視系統狀態、錯誤處理;模組間通訊的簡單性;與可維護性不同;
  4) 與其他系統介面相容性;
  5) 與網路、硬體介面相容性及效能;
  6) 系統安全性;
  7) 系統可靠性;
  8) 業務流程的可調整性;
  9) 業務資訊的可調整性
  10) 使用方便性
  11) 構架樣式的一致性
  注:執行時負載均衡可以從系統性能、系統可靠性方面考慮。
  2、原始碼的組織結構方面的考慮:
  1) 開發可管理性:便於人員分工(模組獨立性、開發工作的負載均衡、進度安排優化、預防人員流動對開發的影響)、利於配置管理、大小的合理性與適度複雜性;
  2) 可維護性:與執行可管理性不同;
  3) 可擴充性:系統方案的升級、擴容、擴充效能;
  4) 可移植性:不同客戶端、應用伺服器、資料庫管理系統;
  5) 需求的符合性(原始碼的組織結構方面的考慮)。

三、程式的執行時結構方面的考慮:
  1、 需求的符合性:正確性、完整性;功能性需求、非功能性需求
  軟體專案最主要的目標是滿足客戶需求。在進行構架設計的時候,大家考慮更多的是使用哪個執行平臺、編成語言、開發環境、資料庫管理系統等問題,對於和客戶需求相關的問題考慮不足、不夠系統。如果無論怎麼好的構架都無法滿足客戶明確的某個功能性需求或非功能性需求,就應該與客戶協調在專案範圍和需求規格說明書中刪除這一需求。否則,架構設計應以滿足客戶所有明確需求為最基本目標,儘量滿足其隱含的需求。(客戶的非功能性需求可能包括介面、系統安全性、可靠性、移植性、擴充套件性等等,在其他小節中細述)
  一般來說,功能需求決定業務構架、非功能需求決定技術構架,變化案例決定構架的範圍。需求方面的知識告訴我們,功能需求定義了軟體能夠做些什麼。我們需要根據業務上的需求來設計業務構架,以使得未來的軟體能夠滿足客戶的需要。非功能需求定義了一些效能、效率上的一些約束、規則。而我們的技術構架要能夠滿足這些約束和規則。變化案例是對未來可能發生的變化的一個估計,結合功能需求和非功能需求,我們就可以確定一個需求的範圍,進而確定一個構架的範圍。(此段From林星)
  這裡講一個前幾年因客戶某些需求錯誤造成構架設計問題而引起系統性能和可靠性問題的小小的例子:此係統的需求本身是比較簡單的,就是將某城市的某業務的全部歷史檔案卡片掃描儲存起來,以便可以按照姓名進行查詢。需求階段客戶說卡片大約有20萬張,需求調研者出於對客戶的信任沒有對資料的總量進行查證。由於是中小型資料量,並且今後資料不會增加,經過計算20萬張卡片總體容量之後,決定使用一種可以單機使用也可以聯網的中小型資料庫管理系統。等到系統完成開始錄入資料時,才發現數據至少有60萬,這樣使用那種中小型資料庫管理系統不但會造成系統性能的問題,而且其可靠性是非常脆弱的,不得不對系統進行重新設計。從這個小小的教訓可以看出,需求階段不僅對客戶的功能需求要調查清楚,對於一些隱含非功能需求的一些資料也應當調查清楚,並作為構架設計的依據。
  對於功能需求的正確性,在構架設計文件中可能不好驗證(需要人工、費力)。對於功能需求完整性,就應當使用需求功能與對應模組對照表來跟蹤追溯。對於非功能需求正確性和完整性,可以使用需求非功能與對應設計策略對照表來跟蹤追溯評估。
  “軟體設計工作只有基於使用者需求,立足於可行的技術才有可能成功。”
  2、 總體效能
  效能其實也是客戶需求的一部分,當然可能是明確的,也有很多是隱含的,這裡把它單獨列出來在說明一次。效能是設計方案的重要標準,效能應考慮的不是單臺客戶端的效能,而是應該考慮系統總的綜合性能;
  效能設計應從以下幾個方面考慮:記憶體管理、資料庫組織和內容、非資料庫資訊、任務並行性、網路多人操作、關鍵演算法、與網路、硬體和其他系統介面對效能的影響;
幾點提示:演算法優化及負載均衡是效能優化的方向。經常要呼叫的模組要特別注意優化。佔用記憶體較多的變數在不用時要及時清理掉。需要下載的網頁主題檔案過大時應當分解為若干部分,讓使用者先把主要部分顯示出來。
  3、 執行可管理性
  系統的構架設計應當為了使系統可以預測系統故障,防患於未然。現在的系統正逐步向複雜化、大型化發展,單靠一個人或幾個人來管理已顯得力不從心,況且對於某些突發事件的響應,人的反應明顯不夠。因此通過合理的系統構架規劃系統執行資源,便於控制系統執行、監視系統狀態、進行有效的錯誤處理;為了實現上述目標,模組間通訊應當儘可能簡單,同時建立合理詳盡的系統執行日誌,系統通過自動審計執行日誌,瞭解系統執行狀態、進行有效的錯誤處理;(執行可管理性與可���護性不同)
  4、 與其他系統介面相容性(解釋略)
  5、 與網路、硬體介面相容性及效能(解釋略)
  6、 系統安全性
  隨著計算機應用的不斷深入和擴大,涉及的部門和資訊也越來越多,其中有大量保密資訊在網路上傳輸,所以對系統安全性的考慮已經成為系統設計的關鍵,需要從各個方面和角度加以考慮,來保證資料資料的絕對安全。
  7、 系統可靠性
  系統的可靠性是現代資訊系統應具有的重要特徵,由於人們日常的工作對系統依賴程度越來越多,因此係統的必須可靠。系統構架設計可考慮系統的冗餘度,儘可能地避免單點故障。系統可靠性是系統在給定的時間間隔及給定的環境條件下,按設計要求,成功地執行程式的概率。成功地執行不僅要保證系統能正確地執行,滿足功能需求,還要求當系統出現意外故障時能夠儘快恢復正常執行,資料不受破壞。
  8、 業務流程的可調整性
  應當考慮客戶業務流程可能出現的變化,所以在系統構架設計時要儘量排除業務流程的制約,即把流程中的各項業務結點工作作為獨立的物件,設計成獨立的模組或元件,充分考慮他們與其他各種業務物件模組或元件的介面,在流程之間通過業務物件模組的相互呼叫實現各種業務,這樣,在業務流程發生有限的變化時(每個業務模組本身的業務邏輯沒有變的情況下),就能夠比較方便地修改系統程式模組或元件間的呼叫關係而實現新的需求。如果這種呼叫關係被設計成儲存在配置庫的資料字典裡,則連程式程式碼都不用修改,只需修改資料字典裡的模組或元件呼叫規則即可。
  9、 業務資訊的可調整性
  應當考慮客戶業務資訊可能出現的變化,所以在系統構架設計時必須儘可能減少因為業務資訊的調整對於程式碼模組的影響範圍。
  10、 使用方便性
  使用方便性是不須提及的必然的需求,而使用方便性與系統構架是密切相關的。WinCE(1.0)的失敗和後來改進版本的成功就說明了這個問題。WinCE(1.0)有太多層次的視窗和選單,而使用者則更喜歡簡單的介面和快捷的操作。失敗了應當及時糾正,但最好不要等到失敗了再來糾正,這樣會浪費巨大的財力物力,所以在系統構架階段最好能將需要考慮的因素都考慮到。當然使用方便性必須與系統安全性協調平衡統一,使用方便性也必須與業務流程的可調整性和業務資訊的可調整性協調平衡統一。“滿足使用者的需求,便於使用者使用,同時又使得操作流程儘可能簡單。這就是設計之本。”
  11、構架樣式的一致性
  軟體系統的構架樣式有些類似於建築樣式(如中國式、哥特式、希臘復古式)。軟體構架樣式可分為資料流構架樣式、呼叫返回構架樣式、獨立元件構架樣式、以資料為中心的構架樣式和虛擬機器構架樣式,每一種樣式還可以分為若干子樣式。構架樣式的一致性並不是要求一個軟體系統只能採用一種樣式,就像建築樣式可以是中西結合的,軟體系統也可以有異質構架樣式(分為區域性異質、層次異質、並行異質),即多種樣式的綜合,但這樣的綜合應該考慮其某些方面的一致性和協調性。每一種樣式都有其使用的時機,應當根據系統最強調的質量屬性來選擇。 
  四、原始碼的組織結構方面的考慮:
  1、 開發可管理性
  便於人員分工(模組獨立性、開發工作的負載均衡、進度安排優化、預防人員流動對開發的影響:一個好的構架同時應有助於減少專案組的壓力和緊張,提高軟體開發效率)、利於配置管理、大小的合理性、適度複雜性;
  1)便於人員分工-模組獨立性、層次性
  模組獨立性、層次性是為了保證專案開發成員工作之間的相對獨立性,模組聯結方式應該是縱向而不是橫向, 模組之間應該是樹狀結構而不是網狀結構或交叉結構,這樣就可以把開發人員之間的通訊、模組開發制約關係減到最少。同時模組獨立性也比較利於配置管理工作的進行。現在有越來越多的的軟體開發是在異地進行,一個開發組的成員可能在不同城市甚至在不同國家,因此便於異地開發的人員分工與配置管理的原始碼組織結構是非常必要的。
  2)便於人員分工-開發工作的負載均衡
  不僅僅是開發出來的軟體系統需要負載均衡,在開發過程中開發小組各成員之間工作任務的負載均衡也是非重要的。所謂工作任務的負載均衡就是通過合理的任務劃分按照開發人員特點進行分配任務,儘量讓專案組中的每個人每段時間都有用武之地。這就需要在構架設計時應當充分考慮專案組手頭的人力資源,在實現客戶需求的基礎上實現開發工作的負載均衡,以提高整體開發效率。
  3)便於人員分工-進度安排優化;
  進度安排優化的前提是模組獨立性並搞清楚模組開發的先後制約關係。利用工作分解結構對所有程式編碼工作進行分解,得到每一項工作的輸入、輸出、所需資源、持續時間、前期應完成的工作、完成後可以進行的工作。然後預估各模組需要時間,分析各模組的並行與序列(順序制約),繪製出網路圖,找出影響整體進度的關鍵模組,算出關鍵路徑,最後對網路圖進行調整,以使進度安排最優化。
  有個家喻戶曉的智力題叫烤肉片策略:約翰遜家戶外有一個可以同時烤兩塊肉片的烤肉架,烤每塊肉片的每一面需要10分鐘,現要烤三塊肉片給飢腸轆轆急不可耐的一家三口。問題是怎樣才能在最短的時間內烤完三片肉。一般的做法花20分鐘先烤完前兩片,再花20分鐘烤完第三片。有一種更好的方法可以節省10分鐘,大家想想。
  4)便於人員分工-預防員工人員流動對開發的影響
  人員流動在軟體行業是司空見慣的事情,已經是一個常見的風險。作為對這一風險的有效的防範對策之一,可以在構架設計中考慮到並預防員工人員流動對開發的影響。主要的思路還是在模組的獨立性上(追求高內聚低耦合),元件化是目前流行的趨勢。
  5)利於配置管理(獨立性、層次性)
  利於配置管理與利於人員分工有一定的聯絡。除了邏輯上的模組元件要利於人員分工外,物理上的原始碼層次結構、目錄結構、各模組所處原始碼檔案的部署也應當利於人員分工和配置管理。(儘管現在配置管理工具有較強大的功能,但一個清楚的原始碼分割和模組分割是非常有好處的)。
  6)大小的合理性與適度複雜性
  大小的合理性與適度複雜性可以使開發工作的負載均衡,便於進度的安排,也可以使系統在執行時減少不必要的記憶體資源浪費。對於程式碼的可閱讀性和系統的可維護性也有一定的好處。另外,過大的模組常常是系統分解不充分,而過小的模組有可能降低模組的獨立性,造成系統介面的複雜。
  2、 可維護性
  便於在系統出現故障時及時方便地找到產生故障的原因和原始碼位置,並能方便地進行區域性修改、切割;(可維護性與執行可管理性不同)
  3、 可擴充性:系統方案的升級、擴容、擴充效能
  系統在建成後會有一段很長的執行週期,在該週期內,應用在不斷增加,應用的層次在不斷升級,因此採用的構架設計等方案因充分考慮升級、擴容、擴充的可行性和便利
  4、 可移植性
  不同客戶端、應用伺服器、資料庫管理系統:如果潛在的客戶使用的客戶端可能使用不同的作業系統或瀏覽器,其可移植性必須考慮客戶端程式的可移植性,或儘量不使業務邏輯放在客戶端;資料處理的業務邏輯放在資料庫管理系統中會有較好的效能,但如果客戶群中不能確定使用的是同一種資料庫管理系統,則業務邏輯就不能資料庫管理系統中;
達到可移植性一定要注重標準化和開放性:只有廣泛採用遵循國際標準,開發出開放性強的產品,才可以保證各種型別的系統的充分互聯,從而使產品更具有市場競爭力,也為未來的系統移植和升級擴充套件提供了基礎。
  5、 需求的符合性
  從原始碼的組織結構看需求的符合型主要考慮針對使用者需求可能的變化的軟體程式碼及構架的最小冗餘(同時又要使得系統具有一定的可擴充套件性)。
  五、寫系統構架設計文件應考慮的問題
  構架工作應該在需求開發完成約80%的時候開始進行,不必等到需求開發全部完成,需要專案經理以具體的判斷來評估此時是否足以開始構建軟體構架。
  給出一致的輪廓:系統概述。一個系統構架需要現有概括的描述,開發人員才能從上千個細節甚至數十個模組或物件類中建立一致的輪廓。
  構架的目標應該能夠清楚說明系統概念,構架應儘可能簡化,最好的構架檔案應該簡單、簡短,清晰而不雜亂,解決方案自然。
  構架應單先定義上層的主要子系統,應該描述各子系統的任務,並提供每個子系統中各模組或物件類的的初步列表。
  構架應該描述不同子系統間相互通訊的方式,而一個良好的構架應該將子系統間的通訊關係降到最低。
  成功構架的一個重要特色,在於標明最可能變更的領域,應當列出程式中最可能變更的部分,說明構架的其他部分如何應變。
  複用分析、外購:縮短軟體開發週期、降低成本的有效方案未必是自行開發軟體,可以對現有軟體進行復用或進行外購。應考慮其對構架的影響。
  除了系統組織的問題,構架應重點考慮對於細節全面影響的設計決策,深入這些決策領域:外部軟體介面(相容性、通訊方式、傳遞資料結構)、使用者介面(使用者介面和系統層次劃分)、資料庫組織和內容、非資料庫資訊、關鍵演算法、記憶體管理(配置策略)、並行性、安全性、可移植性、網路多人操作、錯誤處理。
  要保證需求的可追蹤性,即保證每個需求功能都有相應模組去實現。
  構架不能只依據靜態的系統目標來設計,也應當考慮動態的開發過程,如人力資源的情況,進度要求的情況,開發環境的滿足情況。構架必須支援階段性規劃,應該能夠提供階段性規劃中如何開發與完成的方式。不應該依賴無法獨立執行的子系統構架。將系統各部分的、依賴關係找出來,形成一套開發計劃。
  六、結語
  系統構架設計和千差萬別的具體的開發平臺密切相關,因此在此無法給出通用的解決方案,主要是為了說明哪些因素是需要考慮的。對於每個因素的設計策略和本文未提到的因素需要軟體構架設計師在具體開發實踐中靈活把握。不同因素之間有時是矛盾的,構架設計時需要根據具體情況進行平衡。
 

架構設計中的方法學

架構設計是一種權衡(trade-off)。一個問題總是有多種的解決方案。而我們要確定唯一的架構設計的解決方案,就意味著我們要在不同的矛盾體之間做出一個權衡。我們在設計的過程總是可以看到很多的矛盾體:開放和整合,一致性和特殊化,穩定性和延展性等等。任何一對矛盾體都源於我們對軟體的不同期望。可是,要滿足我們希望軟體穩定執行的要求,就必然會影響我們對軟體易於擴充套件的期望。我們希望軟體簡單明瞭,卻增加了我們設計的複雜度。沒有一個軟體能夠滿足所有的要求,因為這些要求之間帶有天生的互斥性。而我們評價架構設計的好壞的依據,就只能是根據不同要求的輕���緩急,在其間做出權衡的合理性。

1.        目標 
我們希望一個好的架構能夠: 

重用:為了避免重複勞動,為了降低成本,我們希望能夠重用之前的程式碼、之前的設計。重用是我們不斷追求的目標之一,但事實上,做到這一點可沒有那麼容易。在現實中,人們已經在架構重用上做了很多的工作,工作的成果稱為框架(Framework),比如說Windows的視窗機制、J2EE平臺等。但是在企業商業建模方面,有效的框架還非常的少。 
    透明:有些時候,我們為了提高效率,把實現的細節隱藏起來,僅把客戶需求的介面呈現給客戶。這樣,具體的實現對客戶來說就是透明的。一個具體的例子是我們使用JSP的tag技術來代替JSP的嵌入程式碼,因為我們的HTML介面人員更熟悉tag的方式。 
延展:我們對延展的渴求源於需求的易變。因此我們需要架構具有一定的延展性,以適應未來可能的變化。可是,如上所說,延展性和穩定性,延展性和簡單性都是矛盾的。因此我們需要權衡我們的投入/產出比。以設計出具有適當和延展性的架構。 
簡明:一個複雜的架構不論是測試還是維護都是困難的。我們希望架構能夠在滿足目的的情況下儘可能的簡單明瞭。但是簡單明瞭的含義究竟是什麼好像並沒有一個明確的定義。使用模式能夠使設計變得簡單,但這是建立在我熟悉設計模式的基礎上。對於一個並不懂設計模式的人,他會認為這個架構很複雜。對於這種情況,我只能對他說,去看看設計模式。 
     高效:不論是什麼系統,我們都希望架構是高效的。這一點對於一些特定的系統來說尤其重要。例如實時系統、高訪問量的網站。這些值的是技術上的高效,有時候我們指的高效是效益上的高效。例如,一個只有幾十到一百訪問量的資訊系統,是不是有必要使用EJB技術,這就需要我們綜合的評估效益了。 
安全:安全並不是我們文章討論的重點,卻是架構的一個很重要的方面。

規則 

為了達到上述的目的,我們通常需要對架構設計制定一些簡單的規則: 

功能分解 

顧名思義,就是把功能分解開來。為什麼呢?我們之所以很難達到重用目標就是因為我們編寫的程式經常處於一種好像是重複的功能,但又有輕微差別的狀態中。我們很多時候就會經不住誘惑,用拷貝貼上再做少量修改的方式完成一個功能。這種行為在XP中是堅決不被允許的