Tuesday, September 4, 2018

Testability/Dependency Injection in Clojure

在 OOP 語言的時候,因為要處理「可測試性」的問題,常常需要去考慮 dependency injection。但是, Clojure 已經有了 with-redefs 這種可以將任意的 function 都變成 software seams 的 language syntax 了,還需要特別寫 DI 嗎?

上網查了一下,各家有各家的說法,我個人比較認同的說法是這樣子:
原則上不太需要用 DI 去處理 external dependency 的問題,用 with-redefs 即可以。然而,如果某個外部資源它有 life cycle management 的問題,最好要用 component 或是 mount 來處理。

要達成 Testability 不一定要用 DI。有一篇文章 Testing the Clojure way 指出了這一點:
如果在 C# 之類的靜態語言,要做出類似 with-redefs 的語意的話,則需要用 preprocessing seams 的技巧來替換 dependency

再從另一個觀點來看,在 let over lambda 一書指出 let over lambda 其實就是 object 。而 lambda over let over lambda 可以看成是 anonymous class 。順著這個邏輯去想, dependency injection 也可以視為是 higher order function 的一種語意應用。