Feb. 22 13:01~14:20
在部落格中Teddy多次介紹過BDD和DDD,這一集要看看這兩者摻在一起能不能做出「撒尿牛丸」。BDD和DDD兩者可以互相獨立,你可以BDD而不管DDD,反之亦然。但如果合在一起可以讓BDD所找出來的domain model更容易同時被技術與非技術人員接受作為共同溝通的詞彙,變成DDD所說的Ubiquitous Language(通用語言)。
***
範例回顧
▼先看一下step definition前兩條,程式碼非常簡單,開發人員一定看得懂,但是Product Owner看得懂嗎?Stakeholder看得懂嗎?應該看不懂,而且也沒期望讓他們看懂。
▼但是,如果程式改成這樣,會不會更容易閱讀?看到這裡鄉民們一定覺得沒什麼差別啊,就是套一個factory method模式讓InvoiceBuilder自己產生一個instance,然後把setXXX改用withXXX來取代。
▼不管了,先改成這樣試看看。
***
呼叫單元測試幫忙
▼從step definition所能給予InvoiceBuilder的介面設計建議也就這樣,現在改從TDD的角度來看看能不能協助調整InvoiceBuilder。如果可以用下面這種方式操作InvoiceBuilder,程式碼比較接近自然語言…一點點:「產生一個InvoiceBuilder物件,它的營業稅率為0.05,未稅價格為36000,然後透過它開一張發票」。
▼首先修改InvoiceBuilder類別,讓withVATRate和withTaxIncludePrice函數可以支援fluent API。
▼接著改一下Invoice類別。
▼最後單元測試變成這樣。
▼測試通過。
***
對話
開發人員:發票開立之後可以修改嗎?
Product Owner:修改的意思是…
開發人員:例如含稅金額寫錯了能否修改已經開立的發票?
Product Owner:不行喔,開錯就得作廢,發票一經開立不可修改。
開發人員:我們現在有要考慮作廢發票嗎?
Product Owner:現在還不用。
開發人員:好的,那我把發票的實作調整成不可修改。
▼Invoice類別本身原本就沒有setter來修改它的屬性,現在進一步把它的屬性都設成final,然後把它本身也設成final,變成immutable object。
***
結論
完全套用DDD的話系統中會有幾種標準的類別:
- Entity
- Value Object
- Aggregate
- Repository
- Service
這個例子中還沒走到這一步,只是先讓domain model中的InvoiceBuilder類別支援fluent API,讓技術與非技術人員可以用相同(接近)的表達方式來溝通,然後讓Invoice類別的實作更接近問題領域中的「語意」(發票不可修改)。
看到這裡DDD所說的Ubiquitous Language(通用語言)到底包含什麼?以Teddy的理解,domain model和測試案例加起來就是目前系統的通用語言。
***
友藏內心獨白:發票不是可以修改嗎?只要在修改處蓋負責人小章就好了啊XD。
延伸閱讀
- BDD(1):詳盡的文件就是可用的軟體
- BDD(2):大家來吃小黃瓜之Cucumber運作原理
- BDD(3):在Eclipse執行Cucumber-JVM
- BDD(4):第一個Cucumber-JVM範例,上集
- BDD(5):第一個Cucumber-JVM範例,下集
- 在IntelliJ IDEA使用Cucumber(上)
- 在IntelliJ IDEA使用Cucumber(下)
- BDD(6):讓Step找到Step Definition
- BDD(7):使用Transform讓稅金同時支援5%和0.05表達方式
- BDD(8):實作第一個開發票Scenario
- Fluent interface
- FluentInterface
沒有留言:
張貼留言