談到應(yīng)用程序的層次,我們平時所說的層次有兩種:邏輯的層次(layer)和部署的層次(tier)。這兩種層次劃分的目的是不同的,因此劃分方式也有一些差異,能夠為應(yīng)用程序帶來的好處也是不同的。
邏輯層次
邏輯層次(layer)劃分的最重要的目的在于調(diào)整應(yīng)用程序各部分之間的依賴關(guān)系。應(yīng)用程序可以看作數(shù)據(jù)和業(yè)務(wù)規(guī)則的集合,這個集合通過用戶界面與用戶發(fā)生交互。如果不劃分層次,或者只劃分最簡單的層次,系統(tǒng)的結(jié)構(gòu)就會是這樣:數(shù)據(jù)庫處于系統(tǒng)的中心地位,在此之上建立用戶界面,業(yè)務(wù)規(guī)則寫在用戶界面里。
這樣做的問題在于:數(shù)據(jù)庫作為應(yīng)用程序的中心是不合適的,因為數(shù)據(jù)庫只負責存儲數(shù)據(jù),而不能對數(shù)據(jù)做出解釋(這是業(yè)務(wù)規(guī)則的任務(wù)),而業(yè)務(wù)規(guī)則分散在非中心的位置,零散的表達在用戶界面中。一旦需求改變,業(yè)務(wù)規(guī)則必須隨之改變,而業(yè)務(wù)規(guī)則是分散在各處的,我們就要四處尋找業(yè)務(wù)規(guī)則,進行修改。隨著應(yīng)用程序規(guī)模的擴大,這是一項非常艱難的任務(wù)。
為了解決復(fù)雜的依賴關(guān)系,我們創(chuàng)建了業(yè)務(wù)層。典型的邏輯分層結(jié)構(gòu)就是:表示層->業(yè)務(wù)層->數(shù)據(jù)層。
建立業(yè)務(wù)層的方式可以非常簡單:假如我們的應(yīng)用程序要進行多項業(yè)務(wù),我們分析這些業(yè)務(wù)的流程,找出這些流程中共同的部分,提取他們作為獨立的過程,這就形成了最簡單的業(yè)務(wù)層。這樣,不同的界面之間就可以重用業(yè)務(wù)規(guī)則的代碼,從一定程度上解決了依賴關(guān)系的不合理性。這是一種基于過程的方法。但是這樣的方法有兩個問題:
第一:他建立在對系統(tǒng)中的各種業(yè)務(wù)充分了解的基礎(chǔ)之上,要正確的分析各個業(yè)務(wù)流程的細節(jié),否則劃分的流程和提取的共同過程必然有疏漏。但是在實際的開發(fā)過程中,我們往往一開始只了解業(yè)務(wù)的整體情況,對于其細節(jié)是逐漸了解的。并且對于一些隱含的關(guān)系,需要在開發(fā)的過程中才能認識到。有時候采用的一些具體的開發(fā)技術(shù)也會影響到某些業(yè)務(wù)的實現(xiàn)方式,進而對其流程帶來影響。這樣就為過程的分析帶來很大的困難。
第二:基于過程的方法受到需求變化的沖擊比較大。因為這樣的分析方法,在實現(xiàn)的時候是基于業(yè)務(wù)的過程,而不是業(yè)務(wù)的目的。當系統(tǒng)中有業(yè)務(wù)需要變化的時候,會影響到其他具有共同過程的業(yè)務(wù),業(yè)務(wù)之間的依賴是比較嚴重的,對需求變更的適應(yīng)力差。
如果采用面向?qū)ο蟮姆绞?,將業(yè)務(wù)進行抽象,概括實現(xiàn)這些業(yè)務(wù)需要使用的手段(例如需要更新數(shù)據(jù)表、向端口發(fā)送指令、保持業(yè)務(wù)進行的狀態(tài)……),為所有的業(yè)務(wù)制定一個統(tǒng)一的框架,由這個框架決定業(yè)務(wù)執(zhí)行的策略(如何限定業(yè)務(wù)的條件、分哪些步驟、失敗后是重試還是放棄、何時向用戶報告業(yè)務(wù)執(zhí)行的進度……),框架不加區(qū)別的處理所有的業(yè)務(wù)。用戶執(zhí)行一個業(yè)務(wù)的時候,我們只要相應(yīng)的創(chuàng)建一個業(yè)務(wù)對象,將這個對象置于框架內(nèi),監(jiān)視執(zhí)行的進度。這樣,各個業(yè)務(wù)的實現(xiàn)就自然的隔離起來,依賴關(guān)系比較簡單。同時應(yīng)付需求變更也比較容易,獨立的業(yè)務(wù)發(fā)生變更,只要修改一個類,如果多個業(yè)務(wù)的執(zhí)行方式都要改變,則可以從框架上想辦法。
如果為這個框架添加新的機制,使他不僅能夠執(zhí)行業(yè)務(wù)對象,還能夠負責創(chuàng)建和銷毀業(yè)務(wù)對象,就能夠帶來更強大的功能。業(yè)務(wù)框架就進而成為一個業(yè)務(wù)容器。當用戶希望執(zhí)行一個業(yè)務(wù)的時候,我們可以要求業(yè)務(wù)容器創(chuàng)建這個業(yè)務(wù)對象,業(yè)務(wù)容器可以交給我們一個業(yè)務(wù)對象的代理,隱藏真實的對象的位置。實際的執(zhí)行過程可能是分布式的,容器為我們管理業(yè)務(wù)對象的事務(wù)性,保存業(yè)務(wù)執(zhí)行的進度,必要的時候暫停業(yè)務(wù),條件成熟后再重新開始,業(yè)務(wù)完成以后將對象銷毀……這些我們都不必關(guān)心,由容器為我們做。
優(yōu)化應(yīng)用程序內(nèi)部的依賴關(guān)系是劃分邏輯層次的一個重要目的,并不是采用了邏輯層次,依賴關(guān)系自然就優(yōu)化了。層次設(shè)計的好才有這個好處,否則就沒有,甚至可能會更麻煩。層次間的調(diào)用機制可以采用逐層調(diào)用,也可以跨層調(diào)用,都是比較常見的方式。層次間的依賴的方向可以從上到下,也可以從下到上,都是合理的。需要小心的是,兩個層次之間不可以產(chǎn)生互相的依賴,否則會破壞層次結(jié)構(gòu)。比如有A和B兩個層次,要么A依賴B,要么B依賴A,不可以互相依賴。如果必須有層次間互相調(diào)用,則必須采用某些方法轉(zhuǎn)換其中一個方向上的依賴關(guān)系(可以采用的方式諸如delegete,interface,消息,事件等等)。多個層次之間也不應(yīng)該出現(xiàn)循環(huán)的依賴關(guān)系。
部署層次
部署層次(tier)劃分的目的在于增強應(yīng)用程序部署的靈活性,更大限度的利用硬件環(huán)境資源。應(yīng)用軟件對環(huán)境有多方面的需要,比如數(shù)據(jù)存儲的模塊需要服務(wù)器有較強的穩(wěn)定性、容錯性、較高的IO效率,事務(wù)處理模塊則需要運算迅速的處理器和較大的內(nèi)存,而管理終端則需要有較強的表現(xiàn)能力。通常很難有這樣的服務(wù)器滿足多方面的需要,因此我們需要將應(yīng)用程序分為多個層次,部署在不同的位置。
同時,在某些應(yīng)用程序中需要訪問一些敏感的數(shù)據(jù),這些數(shù)據(jù)是不允許或者不可能集中到本地的,這都要求程序在部署方面增加靈活性。
從系統(tǒng)性能的角度說,應(yīng)用程序在部署時劃分合理的層次,可以增加系統(tǒng)的擴展性。當現(xiàn)有的硬件條件不滿足需要的時候,可以通過改變部署方式,提高系統(tǒng)的性能。
比如使用一個服務(wù)器的時候可以滿足100個并發(fā)業(yè)務(wù),當并發(fā)業(yè)務(wù)達到150的時候,可以通過增加服務(wù)器滿足這個要求。這就需要應(yīng)用程序使用多層次的結(jié)構(gòu),缺少必要的層次是不可能進行這樣的擴展的。
再如,我們需要在一個支持20個連接的數(shù)據(jù)庫上建立一個支持100個客戶端的系統(tǒng),這時就必須建立獨立于數(shù)據(jù)庫的連接保持層次。
應(yīng)用程序的部署層次有一些常用的模式,比如B/S結(jié)構(gòu),C/S結(jié)構(gòu),客戶端/應(yīng)用服務(wù)器/數(shù)據(jù)服務(wù)器結(jié)構(gòu),都是一些常用的層次劃分模式。具體采用什么樣的模式要看應(yīng)用程序的需要,假如應(yīng)用程序需要頻繁的訪問客戶本地資源,要求較高的效率,或者要求具有強大的離線處理功能,則采用B/S結(jié)構(gòu)就是不合適的,C/S結(jié)構(gòu)是一個比較好的選擇。如果需要在部署配置方面比較簡單,又要面對不同的客戶端環(huán)境,那么B/S結(jié)構(gòu)就是很好的模式。如果需要建立服務(wù)器組來平衡負載,那么應(yīng)用服務(wù)器則是必不可少的。
部署層次和邏輯層次有一定的關(guān)系,比如說一個程序從邏輯上不分層次,那么在部署的時候要分為多個層次就很難了。但是這兩種層次并不是必須嚴格一致的,比如說,采用“客戶端/應(yīng)用服務(wù)器/數(shù)據(jù)服務(wù)器”的部署層次,并不一定意味著客戶端對應(yīng)著表示層,應(yīng)用服務(wù)器端對應(yīng)著業(yè)務(wù)層,數(shù)據(jù)服務(wù)器就一定是數(shù)據(jù)層。不能把對應(yīng)關(guān)系絕對化,這兩個角度劃分的層次沒有嚴格的對應(yīng)關(guān)系,他們是為了達到不同的目的而劃分的。
例如:在一些軟件系統(tǒng)中,將業(yè)務(wù)邏輯以存儲過程的形式直接寫在數(shù)據(jù)庫中。這樣的系統(tǒng)中,業(yè)務(wù)層與數(shù)據(jù)服務(wù)器是相對應(yīng)的。這樣的業(yè)務(wù)層如果處理的好,一樣具有清晰簡潔的邏輯,維護起來也十分方便。但是這樣顯然會在部署上失去靈活性。
現(xiàn)實的問題
很多人在軟件設(shè)計中常有這樣的體會:在設(shè)計一個軟件體系架構(gòu)的時候,為了能夠簡化軟件系統(tǒng)的邏輯復(fù)雜性,經(jīng)常采用的手段是將一個大的系統(tǒng)分為若干層次。常用的方法是:分解一個龐大系統(tǒng)的各個功能,將其分別部署在多個部件中,每個部件只完成單一的功能,以減弱部件的復(fù)雜程度。部件之間采用一些弱耦合方式進行通信,比如消息、TCP連接等方式。
但是實際的開發(fā)和維護過程中,卻發(fā)現(xiàn)這樣并沒有減輕系統(tǒng)的復(fù)雜程度。部件盡管已經(jīng)從物理上分離,運行在不同的線程、進程、服務(wù)器上,但是部件之間在邏輯上卻有著強烈的耦合關(guān)系,部件之間的接口有著時間、空間上的復(fù)雜交錯關(guān)系,調(diào)用者需要依照復(fù)雜的邏輯次序,調(diào)用被調(diào)用者的接口,保存各次調(diào)用之間的狀態(tài),深入到對方的業(yè)務(wù)過程細節(jié)中。系統(tǒng)的結(jié)構(gòu)沒有因為層次而變得簡潔,反而更加的復(fù)雜。一個業(yè)務(wù)的變更會在多個層次中造成影響,變更的代價更加巨大,沒有起到層次模型應(yīng)有的作用。
造成這個后果的原因在于,設(shè)計者混淆了邏輯層次和部署層次之間的區(qū)別。如果以減小系統(tǒng)的復(fù)雜程度為目的,首要的一點是從邏輯上分開層次,讓各層次對業(yè)務(wù)的處理處于不同的抽象級別。為業(yè)務(wù)行為建立合理的抽象層次,而不是簡單的讓各個部件執(zhí)行業(yè)務(wù)的某個階段,也不是簡單的讓部件甲執(zhí)行ABC業(yè)務(wù),部件乙執(zhí)行XYZ業(yè)務(wù),這是邏輯層次的關(guān)鍵。做到了這一點,才能減小系統(tǒng)的復(fù)雜程度。錯誤的邏輯層次劃分,只能使系統(tǒng)變得更加復(fù)雜。而盲目的劃分部署層次,則是與初始的目的毫無關(guān)系的,也只能增加復(fù)雜性。
部署層次劃分的作用并不在于簡化系統(tǒng)邏輯結(jié)構(gòu),而是增加系統(tǒng)對環(huán)境的適應(yīng)力。
邏輯層次的設(shè)計和部署層次的設(shè)計在軟件開發(fā)中經(jīng)常是交織在一起進行的,他們互相制約,互相影響,有共同的特征。但是這兩種層次劃分方式有著本質(zhì)上的不同,存在著對立的方面,需要開發(fā)者在設(shè)計的時候進行協(xié)調(diào),這也是需要注意的。
談到應(yīng)用程序的層次,我們平時所說的層次有兩種:邏輯的層次(layer)和部署的層次(tier)。這兩種層次劃分的目的是不同的,因此劃分方式也有一些差異,能夠為應(yīng)用程序帶來的好處也是不同的。
邏輯層次
邏輯層次(layer)劃分的最重要的目的在于調(diào)整應(yīng)用程序各部分之間的依賴關(guān)系。應(yīng)用程序可以看作數(shù)據(jù)和業(yè)務(wù)規(guī)則的集合,這個集合通過用戶界面與用戶發(fā)生交互。如果不劃分層次,或者只劃分最簡單的層次,系統(tǒng)的結(jié)構(gòu)就會是這樣:數(shù)據(jù)庫處于系統(tǒng)的中心地位,在此之上建立用戶界面,業(yè)務(wù)規(guī)則寫在用戶界面里。
這樣做的問題在于:數(shù)據(jù)庫作為應(yīng)用程序的中心是不合適的,因為數(shù)據(jù)庫只負責存儲數(shù)據(jù),而不能對數(shù)據(jù)做出解釋(這是業(yè)務(wù)規(guī)則的任務(wù)),而業(yè)務(wù)規(guī)則分散在非中心的位置,零散的表達在用戶界面中。一旦需求改變,業(yè)務(wù)規(guī)則必須隨之改變,而業(yè)務(wù)規(guī)則是分散在各處的,我們就要四處尋找業(yè)務(wù)規(guī)則,進行修改。隨著應(yīng)用程序規(guī)模的擴大,這是一項非常艱難的任務(wù)。
為了解決復(fù)雜的依賴關(guān)系,我們創(chuàng)建了業(yè)務(wù)層。典型的邏輯分層結(jié)構(gòu)就是:表示層->業(yè)務(wù)層->數(shù)據(jù)層。
建立業(yè)務(wù)層的方式可以非常簡單:假如我們的應(yīng)用程序要進行多項業(yè)務(wù),我們分析這些業(yè)務(wù)的流程,找出這些流程中共同的部分,提取他們作為獨立的過程,這就形成了最簡單的業(yè)務(wù)層。這樣,不同的界面之間就可以重用業(yè)務(wù)規(guī)則的代碼,從一定程度上解決了依賴關(guān)系的不合理性。這是一種基于過程的方法。但是這樣的方法有兩個問題:
第一:他建立在對系統(tǒng)中的各種業(yè)務(wù)充分了解的基礎(chǔ)之上,要正確的分析各個業(yè)務(wù)流程的細節(jié),否則劃分的流程和提取的共同過程必然有疏漏。但是在實際的開發(fā)過程中,我們往往一開始只了解業(yè)務(wù)的整體情況,對于其細節(jié)是逐漸了解的。并且對于一些隱含的關(guān)系,需要在開發(fā)的過程中才能認識到。有時候采用的一些具體的開發(fā)技術(shù)也會影響到某些業(yè)務(wù)的實現(xiàn)方式,進而對其流程帶來影響。這樣就為過程的分析帶來很大的困難。
第二:基于過程的方法受到需求變化的沖擊比較大。因為這樣的分析方法,在實現(xiàn)的時候是基于業(yè)務(wù)的過程,而不是業(yè)務(wù)的目的。當系統(tǒng)中有業(yè)務(wù)需要變化的時候,會影響到其他具有共同過程的業(yè)務(wù),業(yè)務(wù)之間的依賴是比較嚴重的,對需求變更的適應(yīng)力差。
如果采用面向?qū)ο蟮姆绞?,將業(yè)務(wù)進行抽象,概括實現(xiàn)這些業(yè)務(wù)需要使用的手段(例如需要更新數(shù)據(jù)表、向端口發(fā)送指令、保持業(yè)務(wù)進行的狀態(tài)……),為所有的業(yè)務(wù)制定一個統(tǒng)一的框架,由這個框架決定業(yè)務(wù)執(zhí)行的策略(如何限定業(yè)務(wù)的條件、分哪些步驟、失敗后是重試還是放棄、何時向用戶報告業(yè)務(wù)執(zhí)行的進度……),框架不加區(qū)別的處理所有的業(yè)務(wù)。用戶執(zhí)行一個業(yè)務(wù)的時候,我們只要相應(yīng)的創(chuàng)建一個業(yè)務(wù)對象,將這個對象置于框架內(nèi),監(jiān)視執(zhí)行的進度。這樣,各個業(yè)務(wù)的實現(xiàn)就自然的隔離起來,依賴關(guān)系比較簡單。同時應(yīng)付需求變更也比較容易,獨立的業(yè)務(wù)發(fā)生變更,只要修改一個類,如果多個業(yè)務(wù)的執(zhí)行方式都要改變,則可以從框架上想辦法。
如果為這個框架添加新的機制,使他不僅能夠執(zhí)行業(yè)務(wù)對象,還能夠負責創(chuàng)建和銷毀業(yè)務(wù)對象,就能夠帶來更強大的功能。業(yè)務(wù)框架就進而成為一個業(yè)務(wù)容器。當用戶希望執(zhí)行一個業(yè)務(wù)的時候,我們可以要求業(yè)務(wù)容器創(chuàng)建這個業(yè)務(wù)對象,業(yè)務(wù)容器可以交給我們一個業(yè)務(wù)對象的代理,隱藏真實的對象的位置。實際的執(zhí)行過程可能是分布式的,容器為我們管理業(yè)務(wù)對象的事務(wù)性,保存業(yè)務(wù)執(zhí)行的進度,必要的時候暫停業(yè)務(wù),條件成熟后再重新開始,業(yè)務(wù)完成以后將對象銷毀……這些我們都不必關(guān)心,由容器為我們做。
優(yōu)化應(yīng)用程序內(nèi)部的依賴關(guān)系是劃分邏輯層次的一個重要目的,并不是采用了邏輯層次,依賴關(guān)系自然就優(yōu)化了。層次設(shè)計的好才有這個好處,否則就沒有,甚至可能會更麻煩。層次間的調(diào)用機制可以采用逐層調(diào)用,也可以跨層調(diào)用,都是比較常見的方式。層次間的依賴的方向可以從上到下,也可以從下到上,都是合理的。需要小心的是,兩個層次之間不可以產(chǎn)生互相的依賴,否則會破壞層次結(jié)構(gòu)。比如有A和B兩個層次,要么A依賴B,要么B依賴A,不可以互相依賴。如果必須有層次間互相調(diào)用,則必須采用某些方法轉(zhuǎn)換其中一個方向上的依賴關(guān)系(可以采用的方式諸如delegete,interface,消息,事件等等)。多個層次之間也不應(yīng)該出現(xiàn)循環(huán)的依賴關(guān)系。
部署層次
部署層次(tier)劃分的目的在于增強應(yīng)用程序部署的靈活性,更大限度的利用硬件環(huán)境資源。應(yīng)用軟件對環(huán)境有多方面的需要,比如數(shù)據(jù)存儲的模塊需要服務(wù)器有較強的穩(wěn)定性、容錯性、較高的IO效率,事務(wù)處理模塊則需要運算迅速的處理器和較大的內(nèi)存,而管理終端則需要有較強的表現(xiàn)能力。通常很難有這樣的服務(wù)器滿足多方面的需要,因此我們需要將應(yīng)用程序分為多個層次,部署在不同的位置。
同時,在某些應(yīng)用程序中需要訪問一些敏感的數(shù)據(jù),這些數(shù)據(jù)是不允許或者不可能集中到本地的,這都要求程序在部署方面增加靈活性。
從系統(tǒng)性能的角度說,應(yīng)用程序在部署時劃分合理的層次,可以增加系統(tǒng)的擴展性。當現(xiàn)有的硬件條件不滿足需要的時候,可以通過改變部署方式,提高系統(tǒng)的性能。
比如使用一個服務(wù)器的時候可以滿足100個并發(fā)業(yè)務(wù),當并發(fā)業(yè)務(wù)達到150的時候,可以通過增加服務(wù)器滿足這個要求。這就需要應(yīng)用程序使用多層次的結(jié)構(gòu),缺少必要的層次是不可能進行這樣的擴展的。
再如,我們需要在一個支持20個連接的數(shù)據(jù)庫上建立一個支持100個客戶端的系統(tǒng),這時就必須建立獨立于數(shù)據(jù)庫的連接保持層次。
應(yīng)用程序的部署層次有一些常用的模式,比如B/S結(jié)構(gòu),C/S結(jié)構(gòu),客戶端/應(yīng)用服務(wù)器/數(shù)據(jù)服務(wù)器結(jié)構(gòu),都是一些常用的層次劃分模式。具體采用什么樣的模式要看應(yīng)用程序的需要,假如應(yīng)用程序需要頻繁的訪問客戶本地資源,要求較高的效率,或者要求具有強大的離線處理功能,則采用B/S結(jié)構(gòu)就是不合適的,C/S結(jié)構(gòu)是一個比較好的選擇。如果需要在部署配置方面比較簡單,又要面對不同的客戶端環(huán)境,那么B/S結(jié)構(gòu)就是很好的模式。如果需要建立服務(wù)器組來平衡負載,那么應(yīng)用服務(wù)器則是必不可少的。
部署層次和邏輯層次有一定的關(guān)系,比如說一個程序從邏輯上不分層次,那么在部署的時候要分為多個層次就很難了。但是這兩種層次并不是必須嚴格一致的,比如說,采用“客戶端/應(yīng)用服務(wù)器/數(shù)據(jù)服務(wù)器”的部署層次,并不一定意味著客戶端對應(yīng)著表示層,應(yīng)用服務(wù)器端對應(yīng)著業(yè)務(wù)層,數(shù)據(jù)服務(wù)器就一定是數(shù)據(jù)層。不能把對應(yīng)關(guān)系絕對化,這兩個角度劃分的層次沒有嚴格的對應(yīng)關(guān)系,他們是為了達到不同的目的而劃分的。
例如:在一些軟件系統(tǒng)中,將業(yè)務(wù)邏輯以存儲過程的形式直接寫在數(shù)據(jù)庫中。這樣的系統(tǒng)中,業(yè)務(wù)層與數(shù)據(jù)服務(wù)器是相對應(yīng)的。這樣的業(yè)務(wù)層如果處理的好,一樣具有清晰簡潔的邏輯,維護起來也十分方便。但是這樣顯然會在部署上失去靈活性。
現(xiàn)實的問題
很多人在軟件設(shè)計中常有這樣的體會:在設(shè)計一個軟件體系架構(gòu)的時候,為了能夠簡化軟件系統(tǒng)的邏輯復(fù)雜性,經(jīng)常采用的手段是將一個大的系統(tǒng)分為若干層次。常用的方法是:分解一個龐大系統(tǒng)的各個功能,將其分別部署在多個部件中,每個部件只完成單一的功能,以減弱部件的復(fù)雜程度。部件之間采用一些弱耦合方式進行通信,比如消息、TCP連接等方式。
但是實際的開發(fā)和維護過程中,卻發(fā)現(xiàn)這樣并沒有減輕系統(tǒng)的復(fù)雜程度。部件盡管已經(jīng)從物理上分離,運行在不同的線程、進程、服務(wù)器上,但是部件之間在邏輯上卻有著強烈的耦合關(guān)系,部件之間的接口有著時間、空間上的復(fù)雜交錯關(guān)系,調(diào)用者需要依照復(fù)雜的邏輯次序,調(diào)用被調(diào)用者的接口,保存各次調(diào)用之間的狀態(tài),深入到對方的業(yè)務(wù)過程細節(jié)中。系統(tǒng)的結(jié)構(gòu)沒有因為層次而變得簡潔,反而更加的復(fù)雜。一個業(yè)務(wù)的變更會在多個層次中造成影響,變更的代價更加巨大,沒有起到層次模型應(yīng)有的作用。
造成這個后果的原因在于,設(shè)計者混淆了邏輯層次和部署層次之間的區(qū)別。如果以減小系統(tǒng)的復(fù)雜程度為目的,首要的一點是從邏輯上分開層次,讓各層次對業(yè)務(wù)的處理處于不同的抽象級別。為業(yè)務(wù)行為建立合理的抽象層次,而不是簡單的讓各個部件執(zhí)行業(yè)務(wù)的某個階段,也不是簡單的讓部件甲執(zhí)行ABC業(yè)務(wù),部件乙執(zhí)行XYZ業(yè)務(wù),這是邏輯層次的關(guān)鍵。做到了這一點,才能減小系統(tǒng)的復(fù)雜程度。錯誤的邏輯層次劃分,只能使系統(tǒng)變得更加復(fù)雜。而盲目的劃分部署層次,則是與初始的目的毫無關(guān)系的,也只能增加復(fù)雜性。
部署層次劃分的作用并不在于簡化系統(tǒng)邏輯結(jié)構(gòu),而是增加系統(tǒng)對環(huán)境的適應(yīng)力。
邏輯層次的設(shè)計和部署層次的設(shè)計在軟件開發(fā)中經(jīng)常是交織在一起進行的,他們互相制約,互相影響,有共同的特征。但是這兩種層次劃分方式有著本質(zhì)上的不同,存在著對立的方面,需要開發(fā)者在設(shè)計的時候進行協(xié)調(diào),這也是需要注意的。
# re: 應(yīng)用軟件的層次劃分 2005-09-14 21:02 蛙蛙池塘
文章寫的非常之好,以前我還真分不子清你說的這兩個層的概念,今天徹底的懂了,呵呵,不過想你提到的那種業(yè)務(wù)層框架,.NET還沒有吧,spring.net還不夠強大吧。