前兩篇:大型系統的支撐,應用系統開發思想的變遷
之前大致說了使用ddd的前期準備,現在可以真正開始實踐了,以我剛剛結束的乙個簡單的經典ddd方式的專案為例子,當然由於比較簡單,所以很多時候會脫離它來介紹一些額外情況,以及這些情況在《ddd》書上提到的解決辦法,另外,說明一下,例子的作用只是例子,只是用來說明可以怎麼做的,但真實情況時未必應該這麼做。這一篇主要是大比例結構的。
首先,簡單提一下專案背景,具體情況就不細說了。今年初公司重組,原本的乙個公司拆分成了三個公司,資訊化部門還是只有我們乙個,經過小半年的時間,業務終於差不多確定下來了(穩定不穩定不好說),我也終於接觸到了真實的業務(以往由於某些原因全是憑空猜的),作為例子的這個專案是做流程審批的,以此為基礎分析後,發現非常適合使用ddd的方式進行設計開發。
前一篇提了,開始乙個專案最重要的是要做的是確定需求中的核心問題,專案對公司來說目的是提高辦公效率,而對我的領導來說更關心的是業績,也就是開發效率,畢竟是公司內部系統,速度在一定程度上優先於其他。我做架構設計,我需求的核心也就是如何讓程式設計師寫更少的**,更快開發出功能,這一點在架構設計開發過程中會佔主導地位。
當然,前提是得滿足完成業務的基本要求。在開始架構的設計前首先要確定系統的範圍,系統都有什麼,也就是一般說的系統邊界。
可以使用大比例結構來確定系統的邊界,當系統比較龐大時,可能會分為很多個模組,太多的模組依然會給人的理解造成壓力,而bounded context雖然可以包含多個模組,但很容易讓系統難以成為完整的整體,這時使用大比例結構可以讓人清楚的看出系統的整體,借助一種更大範圍的劃分,可以清楚的理解元素在系統中位置。這時,當要尋找乙個物件的位置,或新增一項功能的時候就可以輕鬆的定位到要找的位置,負責不同模組的人也可以清楚的知道自己所要做的部分對於總體和對於其他部分的作用,分工不同的程式設計師所做的設計決策可以大體上保持一致。
我的例子不大,使用大比例結構意義不大,基本可以分成兩塊,乙個是審批申請單,乙個是審批流程。審批流驅動原本的暫時還能滿足需求,所以只需要設計申請單的處理就可以了,之後的事情雖然很簡單,但是為了讓它起到例子的作用,先來對它使用下隱喻,比如說,審批流是乙個生產產品的流水線,申請單作為原料一步一步被附加各種加工也就是意見,最後成品的產品即審批結果。
對於業務比較複雜,模型中物件很多,無法一下清晰完整了解模型意義的,可以使用一些對模型分層的方法。這些分層方法的目的是使開發變得更容易。
一、responsibility layer模式:如果每個物件的職責都是手工分配的,將沒有統一的指導原則和一致性,也無法把領域作為乙個整體來處理。為了保持大模型的一致,有必要再職責分配上實施一定的結構化控制。觀察模型中的概念依賴,領域中不同部分的變化頻率和原因。如果領域中有自然的層次結構,就可以作為主要的職責。這些職責描述了系統的高階目的和設計。領域中的物件的職責都應清晰的位於乙個職責層中,層都應該反映出現實狀況,而不是設想的狀況。
當需要按職責分層時,可先分為作業層和潛能層分別包含「作業」職責和「能力」職責,如果有需要根據業務制定決策時增加決策層,如果可以將指定決策的規則抽取出來時策略層,以及介於作業和策略之間的承諾層,evolving order具體使用需要看自己情況隨機應變,具體哪種方法好,要不要這麼分層都是根據自己的實際情況決定的,感覺到彆扭就要考慮換一種方法,切忌生搬硬套。
潛能層:資源(包括人力資源)一集這些資源的組織方式是潛能層的核心。這一層關心的是能做什麼。潛能也包括臨時資產,但主要依賴臨時資產的可將臨時資產獨立一層,比如capability層。
作業層:正在做什麼,利用潛能做了什麼。通常作業層物件可以引用潛能層物件,甚至可由潛能層物件組成,但潛能層物件應該引用作業層物件。
大部分此類領域系統中,這兩層就夠了。它們可以跟中當前狀態和執行的作業計畫,已經問題報告等。但跟蹤往往是不夠的。當專案腰圍使用者提供指導或自動制定一些決策時,就需要另外一組職責。
決策支援層:應該採取什麼行動或制定什麼策略。這個層是用來做出分析和制定決策的。它可以對較低層的資訊進行分析。它對較低的層如作業層或潛能層有概念上的依賴。
策略層:軟體實施了詳細的業務規則或法律需求,這些可以形成乙個層次。可以使用規則引擎,也可以作為引數傳遞給其他層的方法。
在一些特別情況下,潛能層可能會被合併到作業層,比如保險公司在考慮籤保單承擔理賠責任時,要根據當前業務的多樣性判斷是否有能力承擔風險,這類情況通常會出現一種層次是對客戶做出的承諾。這個層次具有策略層的性質,因為它表述了一些指導未來運營的目標;同時也有作業層的性質因為承諾是作為後續業務活動的一部分而出現和變化的。潛能層和承諾層並不互斥,可以並存。但是一定要注意,層次不要太多,否則為了解決複雜性使用的分層層次就會造成新的複雜性,大比例結構要保證嚴格的精簡。
另外,在分層時,可以借助並保留一些有用的特徵:
1.場景描述:層應該能夠表達出領域的基本實現或顯示出業務的優先順序。
2.概念依賴性:較高層概念的意義應該依賴較低層,低層概念的意義應該獨立於較高的層。
3.概念輪廓:應該能夠容許不同層的物件之間必須的不同頻率的變化。
舉個分層的例子,首先從兩層開始,作業層是計畫的活動,日常活動的核心,比如我的例子中作業的物件就是申請單據,包含相應的單據型別的流轉規則、條件和計畫要流轉部門的職位。潛能層反應執行作業時所能利用的資源,比如。。。(話說這個比如我想了很長時間,因為是拿專案硬充例子沒辦法)審批節點上有許可權的部門職位的人,也就是申請單流轉到需要某個職位審批時,這個職位上的人或人們之一是可以審批的。如圖:
上圖中路徑選擇並不是當前的作業,而是用來決定流轉的下乙個節點,流程線路分叉時選擇流轉方向或者改變流轉線路的。這時第三層「決策支援」層出現了,這一層為使用者提供用於指定計畫和決策的工具。它具有自動制定一些決策的潛能(如某原料採購成本變化,自動選擇該申請單由事業部經理決策還是主管副總裁決策)。 這裡需要說明的是「流程線路」,流程線路中包含所有流經的部門職位,是對當前申請單的乙個總體的作業範圍,當前申請單並不一定會路過起內的多有路線,而決定其路過路線的就是」路徑選擇「。以上,路徑選擇應該放入決策支援層,如圖:
至於策略層什麼的,這個專案是在簡單了點,就不舉例子了。另外,有時會有些特別情況,比如說作業層的處理結果出現了錯誤,比如說流轉節點的判斷條件出現了例外情況不符合規則,這種情況需要決策層提供如何處理,是退回還是通知,但較低層是不能依賴較高層的,這種時候可以採用事件機制,作業層狀態變化時產生事件由策略層監聽。如果事件違反規則,則執行特定的規則處理,或生成事件反饋給決策層以便決策層決策。
二、knowledge level模式:一組描述另一組物件應用哪些行為的物件。兩組物件的關係在表象上有些類似於貧血模型及其對應的服務類,只不過這裡的貧血物件和服務類都是物件或聚合。一組物件是我們需要的模型,而另一組物件是乙個描述模型的模型。模式的兩個級別分別是知識級別和操作級別。建立一組不同的物件,用它們來描述和約束基本模型的結構和行為。把這些物件分成為兩個級別,乙個是非常具體的級別,另乙個級別則提供了一些可供使用者或超級使用者定製的規則和知識。
這一模式主要解決的問題是,如果在乙個應用程式中,物件的角色和他們之間的關係在不同的情況下有很大變化,為了兼顧各種不同的情況,物件需要引用其他的型別,或者需要具備一些在不同情況下包括不同使用方式的屬性。具有相同資料和行為的類可能會大量增加,而這些類的唯一作用只是為了滿足不同的組裝規則。再勉強舉個例子吧,流程審批時,當審批職位為合同管理員時,有一項特殊職能,是分配合同號,使用此模式來表達設計如圖:
這個圖參考個意思就好了,不要關心它是什麼圖,也不要在意規不規整什麼的。。。
三、pluggable component framework 模式:基於相同的一些抽象但分別獨立設計的程式互操作的情況,可以通過將這些程式設計為元件,通常所有元件都插入到乙個**hub上,這個hub支援元件所需的協議(可能有多個多種),並且知道如何與它們所提供的介面對話。從介面和互動中提煉出乙個abstract core,並建立乙個框架,這個框架要允許這些介面和各種不同的實現被自由替換。同樣,無論是什麼應用程式,只要它嚴格地通過abstract core的介面進行操作,那麼就可以允許它使用這些元件。高層抽象被識別出來,並在整個系統範圍內共享。
這種模式有幾個缺點。乙個是它需要高精度的介面設計和乙個非常深入的模型,以便把一些必要的行為捕獲到abstract core中。另乙個很大的缺點是它只為應用程式提供了有限的選擇。如果乙個應用程式需要使用一種非常不同的方法,那麼可插入式元件框架將起到妨礙作用。
這種模式的使用並不常見,我這個專案有乙個類似的用法,上面說的的申請單,申請單聚合大概如下圖:
這個聚合只是個抽象的聚合,其中業務資訊有可能是專案,有可能是合同,也有可能是發票等等,申請單資訊也會隨著型別不同而有不同的內容,明細就更不用說,這個明細就是乙個抽象核心,不同種類的業務資訊和申請單就可以通過繼承這個抽象核心並實現其中介面來實現插入,與系統中其他的模組、上下文進行對話,比如說被流程審批等等。
大比例結構大致就這樣了,如果不順利的話,後面我會把這個專案細緻的事情都寫一下的,或許。準備是作為乙個ddd入門的系列來寫,不過我比較隨性,而且喜歡走神,看緣分吧。。。
DDD實踐切入點 二
最近發現下面關於上下文的理解有些問題,不太好改,暫時先不改了 承前 大型系統的支撐,應用系統開發思想的變遷,ddd實踐切入點 一 領域模型不統一時,會有一些問題,比如 限制了整合,增加溝通成本,看上去不優雅。但大型系統領域模型完全統一並不是一種可行的經濟有效的做法。強行統一模型會遇到一些問題 1.遺...
市場切入點
切入點 通俗點,就是突破口,即解決某個問題時應該最先著手的地方。尋找市場切入點,主要從市場分析和產品定位兩方面來入手 接下來舉例說明如何尋找市場切入點,選擇物件 企鵝fm。1.市場分析 1 swot分析 其中,s strengths 是優勢,w weaknesses 是劣勢,o opportunit...
Spring AOP 定義切入點
首先我們編寫了通知advice,但是我們還不能表達在應用系統的什麼地方應用這些通知,切入點決定了乙個特定類的特定方法是否滿足特定規則,如果滿足則通知就應用到該方法上,spring的切入點可以讓我們靈活的定義在什麼地方應用通知。spring的切入點框架的核心介面pointcut public inte...