在〈軟體設計需面對現實〉一文中,我曾針對 Gameboy 提出「用 real world 的直觀來認知 model ,這有點危險」提出個人的看法。對此 Gameboy 為其觀點 defend,然而在討論過程中卻因為對文字感受不同而造成一些爭論。因此,我認為有必要再進一步地探討「用 real world 的直觀來認知 model 」這個主題,以避免不必要的誤會。
基本上我和 Gameboy 對「real world」的定義不同,Gameboy 提到:
因為我看到太多 beginner 的抽象化是
僅僅源自於他們的直觀認知
而非從 Requirement 下手
但 Real World 中直觀的名詞
不見得適合作為 Domain Model 中的 Entity
但卻往往被他們誤植於 Domain Model 中
由上可知 Gameboy 所言之 real world 其實指的是系統開發人員對系統的初步直覺認知,但在未經需求分析之前,容易落入以技術來主導需求,而使領域模型變成與現實問題領域脫節。Gameboy 的看法並沒有錯,但 Gameboy 說的「real world」與我所認知的「real world」並不一樣,我擔心如果沒有界定清楚,言者無心,聽者有意,很讓初學者落入「言語的流沙河」的陷阱-對軟體設計錯誤認知的來源。
我所認知的「real world」是指對領域專家對問題領域的真實認知,也就是洞察問題領域的認知。領域專家多半不懂我們 modeling 的工具與技術,只有當我們提供 model 給他們看時,他們才會大致理解我們的 model 有沒有涵蓋他們的需求。在實務上,許多技術人員卻很喜歡用技術的角度來 modeling,然後告訴使用者這就是系統的領域模型,結果是這樣的 model 在真實世界的問題領域上一點都不直觀,因為牽涉了太多了技術細節(眉角),根本就不是領域概念的 what to do,而是技術實作的 how to do,這樣的領域模型怎麼可能做到概念上的抽象化呢,抽象化不足,後續必然面臨以技術層次主導需求的惡果-更大的複雜度與更小的彈性。
認清了我和 Gameboy 所認定 real world 的不同後,我們來看看 Gameboy 用來解釋「用 real world 直觀的認知來 model,這有點危險」的例子:
比如以 “汽車” 為例
“汽車” 在資產系統、或進銷存系統、或在某某系統
不一定都會被 model 成汽車
可能是 Item 或 Asset 或 anything else
也就是要看清楚 Problem Domain
(其實也就是您在本文的題旨)
會講出這樣的話
「用 real world 直觀的認知來 model,這有點危險」。
是看到有些初學者容易犯這樣的問題 (汽車不見得在業務需求裡都會被視為 “交通工具\”)
就這個例子而言,汽車這個實體在不同的系統會看待成不同的概念,不一定會被 modeling成「交通工具」。其實領域模型是代表我們對真實世界的一種(不是唯一)觀點,它用來說明真實世界的概念是如何運作的,但正如傑出的物理科學家霍金在《胡桃裡的宇宙》中一書曾說過的:「模型並不代表世界的真實狀態,它只能用來合理說明世界所發生的現象」,任何模型都會有所謂的前提假設(assumptions)與限制(constraint)-即在概念上恆為真與現實中必須滿足的條件的存在,因為對於一個複雜系統,我們所不知道的遠比我們知道的還要多,如果沒有用這些條件的限制使問題單純一些,我們根本無法將問題模式化。
所以對於領域建模而言,認清真實世界的問題,就是發展模型的前提假設與限制,以 Gameboy 的例子而言,不同系統的領域模型其前提假設與限制也會不同,所以汽車當然不可能都被看待成交通工具,如果實際上發生這樣的繆誤,其實是代表建模者不夠了解 real world,而非 real world 的直觀有問題。
以管理的角度而言,對 triple constraint(規模、時程、成本及品質四變數)的管理,其中規模的限制就包含了對真實世界的前提假設與限制。這是以軟體專案的整體角度而言,而非以專案成員特定的角色來看,對於專案管理者而言,所謂的 real world 的直觀是不應該包含某些徧見的。
對問題採用不同的觀點會對 Business Semantic 有不同的認知,所以之前主要想表達的並不在於類別該用 is-a 或 has-a,類別設計該採用繼承或是組合並不是必然的,它們是自然而然偶然成形的,用 is-a 或 has-a 實作,只是一種手段。我們要培養應無所住而生其心的智慧,認清所謂的直觀是相對的,亦即當問題焦點變化時,原來的直觀就變成了「本來無一物」,既然如此,那我們「何須惹塵埃」呢?
雖然不當的繼承會導致惡果,但過於複雜的組合關係更是不必要複雜度的原凶,常見有些設計者太早採用 State 或 Strategy 樣式反而混淆了設計的焦點,最後卻栽入沒有必要的設計。如果我們沒有認出真正的問題的關鍵,您怎能期待您的 model 可以抓到重點,沒有重點,根本就不必奢言封裝、抽象化或多型!真實世界的問題往往是非結構化的層面比較大,要用結構來提供解決方案,您的系統結構必須充分考量合適的系統行為,缺少系統行為的系統結構,是不會有系統完整語意的。
GameBoy : Hi Hi
同人 : … 眉角
GameBoy : 用台語發音 ? it’s funny u said that … 🙂