《領域驅動設計精簡版》讀書筆記(3)——面向深層理解的重構

持續重構

重構是不改變應用行爲而重新設計代碼以讓它變得更好的過程,重構通常是非常謹慎的,按照小幅可控的步驟進行,以確保不破壞原有的功能和引入某些缺陷,通過自動化測試可以有效保障重構的代碼質量。基於某些重構模式的自動化重構工具可以讓重構變得更加容易。還有另一種類型的重構,跟領域和它的模型相關,有時我們會對領域有新的理解,這讓有些事物變得更清晰,或者兩個元素間的關係被發現。所有的這些會通過重構被包括到設計中。讓擁有表現力的代碼更易讀和理解是非常重要的。通過閱讀代碼,我們可能不光了解代碼是什麼,同時瞭解它爲什麼要這樣。只有這樣才能讓代碼真正捕獲模型的主旨。建模步驟:

  1. 關於建模的第一件事是閱讀業務規範,從中尋找名詞和動詞。名詞被轉換成類,而動詞則成爲方法。這是一種簡化,將產生淺層次的模型。
  2. 所有的模型開始時都缺乏深度,但我們可以面向越來越深的理解來重構模型。這要求設計必須靈活,僵硬的設計很難做重構。

突顯關鍵概念

當我們跟領域專家交談時,我們交互了很多的思想和知識。某些概念成爲了通用語言,但也有些一直未被重視。它們是隱式概念,用來解釋以及在領域中的其他的概念。在精化設計的過程中,某些隱式概念吸引了我們注意力。我們發現它們當中的某些在設計中擔當了重要的角色。因此我們需要將這些概念顯式化。我們應該爲它們建立類和關係。當它們發生時,我們就擁有了突破的機會。

有時設計的部分可能不會那麼清晰,一堆關係會讓路徑的計算變得難以進行,或者計算的過程會複雜到難以理解。這在設計中顯得極其笨拙,但這也是尋找隱藏的概念的絕佳之所,可能我們錯過了什麼。如果某個關鍵概念在破解謎團時缺失了,其他的事物就不得不替代它完成它的功能。這會讓某些對象變胖,給它們增加了一些本不應該屬於它的行爲。設計的清晰度受到了破壞。努力尋找是否有缺失的概念,如果找到一個,就把它顯式化。

在讓概念顯式化時,還有其他一些非常有用的概念:約束、過程和規約。約束是一個很簡單的表示不變量的方式。無論對象的數據發生了何種變化,都要考慮不變量。這可以簡單地通過把不變量的邏輯放置在一個約束中去實現它。下面是一個簡單的案例,其目的是爲了解釋這個概念,而不是爲了表現對相似案例的建議方法。
書架模型
我們可以向一個書架添加書籍,但是我們永遠不能增加超過它容量的部分。過程通常在代碼中被表現爲 procedure。從我們開始使用面嚮對象語言後我們就不再用一個過程化的方法,所以我們需要爲過程選擇一個對象,然後給它增加行爲。最好的實現過程的方式是使用服務。

通過規約也可以將概念顯式化,規約可以用來測試一個對象是否滿足特定的條件。領域層包含了應用到實體和值對象上的業務規則。那些規則通常與它們要應用到的對象合成一體。在這些規則中,某些只是用來回答“是”和“否”的一組問題的,某些規則可以被表現成一系列操作布爾值的邏輯上的操作,最終結果也是一個布爾值。

一個這樣的案例是在一個客戶對象上執行測試,看它是否符合特定的信用條件。這個規則可以被表現成一個方法,起名叫 isEligible(),並且可以附加到客戶對象上。但這個規則不是嚴格基於客戶的數據進行操作的一個簡單的方法。評估規則涉及到驗證客戶的信用,檢查他過去是否支付過他的債務,檢查他是否具有足夠的餘額等。這樣的業務規則可能非常的大,非常複雜,讓對象的功能腫脹,不再滿足其原始的目的。在這種情況下我們可能會試圖將整個規則移動到應用層,因爲它看上去已經超越了領域層了。實際上,到了重構的時候了。規則應該被封裝到一個負責它的對象中,這將成爲客戶的規約,並且被保留在領域層中。新的對象將包含一系列布爾方法,這些方法用來測試一個客戶對象是否符合某種信用。每一個方法擔負了一個小的測試的功能,所有的方法可以通過組合對某個原始問題給出答案。如果業務規則不能被包含到一個規約對象中,對應的代碼會遍佈到無數的對象中,讓它不再一致。規約用來測試對象是否滿足某種需要,或者他們是否已經爲某種目的準備完畢。它也可以被用來從一個集合中篩選一個特定的對象,或者作爲某個對象的創建條件。通常情況下,一個單個的規約負責檢查是否滿足一個簡單的規則,若干個這樣的規約組合在一起表現一個複雜的規約。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章