l

2017年2月24日 星期五

BDD(9):DDD乍現

Feb. 22 13:01~14:20

屏幕截图 2017-02-22 14.15.27

 

在部落格中Teddy多次介紹過BDD和DDD,這一集要看看這兩者摻在一起能不能做出「撒尿牛丸」。BDD和DDD兩者可以互相獨立,你可以BDD而不管DDD,反之亦然。但如果合在一起可以讓BDD所找出來的domain model更容易同時被技術與非技術人員接受作為共同溝通的詞彙,變成DDD所說的Ubiquitous Language(通用語言)

***

範例回顧

▼先看一下step definition前兩條,程式碼非常簡單,開發人員一定看得懂,但是Product Owner看得懂嗎?Stakeholder看得懂嗎?應該看不懂,而且也沒期望讓他們看懂。

屏幕截图 2017-02-22 13.17.17

 

▼但是,如果程式改成這樣,會不會更容易閱讀?看到這裡鄉民們一定覺得沒什麼差別啊,就是套一個factory method模式讓InvoiceBuilder自己產生一個instance,然後把setXXX改用withXXX來取代。

屏幕截图 2017-02-22 13.21.07

 

▼不管了,先改成這樣試看看。

屏幕截图 2017-02-22 13.26.50

***

呼叫單元測試幫忙

▼從step definition所能給予InvoiceBuilder的介面設計建議也就這樣,現在改從TDD的角度來看看能不能協助調整InvoiceBuilder。如果可以用下面這種方式操作InvoiceBuilder,程式碼比較接近自然語言…一點點:「產生一個InvoiceBuilder物件,它的營業稅率為0.05,未稅價格為36000,然後透過它開一張發票」。

屏幕截图 2017-02-22 13.44.55

 

▼首先修改InvoiceBuilder類別,讓withVATRate和withTaxIncludePrice函數可以支援fluent API

屏幕截图 2017-02-22 13.45.39

 

▼接著改一下Invoice類別。

屏幕截图 2017-02-22 13.55.37

 

▼最後單元測試變成這樣。

屏幕截图 2017-02-22 13.56.49

 

▼測試通過。

屏幕截图 2017-02-22 13.57.56

***

對話

開發人員:發票開立之後可以修改嗎?

Product Owner:修改的意思是…

開發人員:例如含稅金額寫錯了能否修改已經開立的發票?

Product Owner:不行喔,開錯就得作廢,發票一經開立不可修改。

開發人員:我們現在有要考慮作廢發票嗎?

Product Owner:現在還不用。

開發人員:好的,那我把發票的實作調整成不可修改。

▼Invoice類別本身原本就沒有setter來修改它的屬性,現在進一步把它的屬性都設成final,然後把它本身也設成final,變成immutable object

屏幕截图 2017-02-22 14.02.15

***

結論

完全套用DDD的話系統中會有幾種標準的類別:

  • Entity
  • Value Object
  • Aggregate
  • Repository
  • Service

這個例子中還沒走到這一步,只是先讓domain model中的InvoiceBuilder類別支援fluent API,讓技術與非技術人員可以用相同(接近)的表達方式來溝通,然後讓Invoice類別的實作更接近問題領域中的「語意」(發票不可修改)。

看到這裡DDD所說的Ubiquitous Language(通用語言)到底包含什麼?以Teddy的理解,domain model和測試案例加起來就是目前系統的通用語言。

***

友藏內心獨白:發票不是可以修改嗎?只要在修改處蓋負責人小章就好了啊XD。

 

延伸閱讀

  1. BDD(1):詳盡的文件就是可用的軟體
  2. BDD(2):大家來吃小黃瓜之Cucumber運作原理
  3. BDD(3):在Eclipse執行Cucumber-JVM
  4. BDD(4):第一個Cucumber-JVM範例,上集
  5. BDD(5):第一個Cucumber-JVM範例,下集
  6. 在IntelliJ IDEA使用Cucumber(上)
  7. 在IntelliJ IDEA使用Cucumber(下)
  8. BDD(6):讓Step找到Step Definition
  9. BDD(7):使用Transform讓稅金同時支援5%和0.05表達方式
  10. BDD(8):實作第一個開發票Scenario
  11. Fluent interface
  12. FluentInterface

沒有留言:

張貼留言