l

2019年12月4日 星期三

把問題寫成一個問句

Dec. 04 08:29~10:25


選擇解決方案的困難

使用設計模式(design pattern)超過20年,也教了好幾年的設計模式。Teddy發現一個常見的問題,就是遇到設計問題時,不知道要套用哪一個設計模式

Teddy一直覺得,讀模式除了模式名字(Name)以外,最重要的就是要知道模式要解決什麼問題 (Problem),最好能夠把問題寫成一個問句,用一句話就能說出該模式存在的目的。

如此一來,在套用模式的時候,針對解決相同問題的模式,只要考慮他們彼此之間forces的差異,就可以判斷哪一個解決方案比較合適。

可惜很多模式的撰寫風格並沒有明確指出模式所要解決的問題,而是使用敘述性的文字把問題與forces甚至是解決方案混在一起談論。讀者只關注到模式的解決方案,導致誤用模式的情況。

***

Value Object

▲翻拍自《Domain-Driven Design: Tackling Complexity in the Heart of Software》,p.98 。

上圖為《Domain-Driven Design: Tackling Complexity in the Heart of Software》(藍皮書)書中描述Value Object模式的段落,黑體字的部分指出幾點問題,這個看起來好像是Value Object所要解決的問題(從Teddy的角度來看,黑體字的部分比較像是forces,也就是問題的限制或特徵)。但是,讀完之後還是不知道如何用一句話說明Value Object的Problem。

黑體字之後突然冒出一句「An object that represents a descriptive aspect of the domain with no conceptual identity is called a VALUE OBJECT 」,這看起來像是在說明解決方案。一下子討論問題,突然又冒出解決方案(書中下一頁才是詳細的解決方案章節),更容易讓讀者抓不住模式所要解決的問題到底是什麼。

***

改寫練習

藍皮書第五章A Model Expressed in Software提到了四個模式:ENTITY、VALUE OBJECT、SERVICE、MODULE,Teddy認為它們都要解決一個共同的大問題。因為forces不同,所以衍生出四種不同的解決方案(四個不同的模式)。

在此Teddy試著改寫前三個模式,它們擁有相同的Context以及Problem:

Context:你正在使用物件導向方法定義領域模型。

Problem:你如何表達物件(領域元素)?

***

ENTITY

Forces:

  • 物件不是由其屬性所定義。
  • 兩個屬性不同的物件可能被視為相同。
  • 即使兩個物件具有相同的屬性,它們可能被視為不同的物件。
  • 弄錯物件辨識碼可能導致資料損壞。

Solution:將物件歸類為ENTITY如果它是透過辨識碼而不是自身的屬性來區分。使此辨識碼成為模型中其定義的主要依據。使類別定義保持簡單,並專注於生命週期的連續性和標識。定義一種區分每個物件的方法,無論其形式或歷史如何皆可依據該方找到想要找的物件。將需求中依據屬性匹配物件的要求改成依據辨識碼。定義一個保證為每個物件匹配產生唯一結果的操作,可能透過附加一個保證唯一的符號來實現。這種標識方式可能來自外部,也可能是系統為系統創建的任意標識符號,但必須與模型中的辨識碼相對應。模型必須規範物件相等的定義。

***

VALUE OBJECT

Forces:

  • 物件由它們的屬性定義。你只關心它們是什麼,而不關心它們是誰。
  • 紀錄物件的識別碼至關重要,但是將識別碼附加到每個物件身上可能會損害系統性能,增加分析工作並弄亂模型,使所有物件看起來都一樣。

Solution:當你只關心物件的屬性時,將物件分類為VALUE OBJECT。使它表達其傳達屬性的含義並賦予它相關的功能。將VALUE OBJECT視為不可變。不要給它任何識別碼,並避免為了維護ENTITIES所需的設計複雜性。

***

SERVICE

Forces:

  • 領域操作(domain operations)本質上是活動或動作,而不是事物。
  • 領域操作無法被歸屬於某個ENTITY或VALUE OBJECT的自然職責時。

Solution:在模型中增加一個操作,作為代表SERVICE的獨立介面。根據模型的語言定義介面,並確保操作名稱是UBIQUITOUS LANGUAGE的一部分。使SERVICE為無狀態。

***

以上內容大多出自藍皮書,Teddy只是把格式重新調整,抓出Context與問題。以後看到ENTITY、VALUE OBJECT、SERVICE,鄉民們第一個想到的就是「設計領域物件嘿用得到」(這是它們的Context)。接著問題就是有哪幾種領域物件的種類?依據不同的forces,可以分成三種不同的領域物件。

如果用這種方式去思考與記憶,Teddy覺得比較不會在藍皮書中所提到的一堆模式中迷路。

***

動動腦

同樣的內容,為什麼有些人可以用很有條理的方式讓別人聽懂,有些人卻講得非常冗長,讓人越聽越迷糊?!

模式的六大格式是一種很好的收納知識方法,鄉民們可以自己練習一下,找幾個DDD書中其他模式,把它們的問題、解決方案,以及forces抓出來。

練習過後會產生和吃「瀨尿牛丸」的效果,人都變聰明了!

***

友藏內心獨白:練習把飯菜裝進六個格子的便當盒裡面。

沒有留言:

張貼留言