Introduction
DIP 應該很常見, 只是常常在談的時候會發現大家忘記了.
因此特別紀錄一下使用 DIP 實質上的好處.
Assumption
- 我們大多會希望 business logic code 可以乾淨穩定
- 有乾淨穩定的 business logic code, 就可以寫穩定的 unit test code
- 如此未來商業邏輯有改變的時候, 如果邏輯有衝突, 或是程式有問題很快就可以 flush
Reality
- 在沒有仔細思考的情況下, 分層式規劃結果無法有乾淨的 business logic code
- 例如, 假設 DB 是 PostgreSQL, MQ 則是 Kafka
- 很容易程式會出現 MyDomainService depends on MyDomainRepositoryHibernateImpl
- 這樣的架構就變成 business logic code depends on implementation
- 如此, 無法寫出穩定的 business logic test code, 因為都"必須"直接由 domain code 直接依賴 Hibernate & Kafka...
- 一個是需要準備 Hibernate & Kafka 的環境 or mock, 可能有些細微的調整沒藏好, 會導致一點小調整都可以讓測試壞掉

Solution
- 為了區隔出乾淨的 business logic code, 我們可以替 repository 提出一個 interface
- 如此, business logic code 僅止於 MyDomainRepository 以及 MyDomainMessageSender
- 同時, 也要注意 interface 上不可以出現底層的相關資訊
- 例如 MyDomainMessageSender 的 interface 不該出現 topic 這種 Kafka 概念的資訊 (除非我們自己訂一層 abstraction layer)
- 這時候就會看到為何像是 spring-data 會支援直接訂一個 interface 就可以透過 convention access DB

Besides
- 同樣的概念也可以套用在不同的 component
- 例如 application 跟很多外部系統界接, 所以程式裡面有分成不同的 component
- 透過 DIP, 可以把其他 system 的實作與主要的 business logic 獨立開來
- 如此就可以直接在測試描述對於外部喜統的 expectation, 而且不用為了 business logic test code 準備外部系統的細節(在目前的例子, 不用準備 gRPC and Kafka)
沒有留言:
張貼留言