2013-04-08 274 views
4

我想在clojure中創建一個模塊化應用程序。假設我們有一個博客引擎,它由兩個模塊組成,例如 - 數據庫模塊和文章模塊(用於存儲博客文章的東西),所有這些模塊都帶有一些配置參數。Clojure模塊依賴關係

因此 - 文章模塊依賴於存儲,並且具有兩個文章模塊和數據庫模塊(具有不同參數)的實例允許我們在兩個不同的數據庫中託管兩個不同的博客。

我試圖爲每個初始化模塊實時創建新的命名空間,並使用部分應用的參數在此命名空間中定義函數。但我認爲,這種方法是某種黑客行爲。

什麼是正確的方法來做到這一點?

回答

2

「模塊」是一個名詞,如Steve Yegge的'Kingdom of Nouns'中所述。

儘可能地堅持其參數(動詞)的非副作用或純函數,除了抽象的最高級別。不管你喜歡,你都可以組織這些功能。在最高級別上你會有一些應用程序狀態,但有很多方法可以管理它,但我最常用的方法是在clojure協議下隱藏這些頂級服務,然後在clojure記錄中執行它(可能會存在對數據庫連接的引用或者其他)。

此方法最大限度地提高了靈活性,並防止您將自己寫入角落。這與java的依賴注入是一致的。 Stuart Sierra最近在Clojure/West 2013上就這些主題做了一個很好的演講,但該視頻尚未公佈。

請注意與您的方法不同之處。您需要將對象的管理和解析從其生命週期中分離出來。將它們綁定到名稱空間是快速訪問的,但它意味着您編寫的任何函數都會作爲使用該代碼的客戶端訪問全局狀態。通過協議,可以將全局狀態的實現細節與訪問接口分開。

如果您需要一個爲什麼這很有用的激勵性示例,請考慮如何攔截對全球可訪問的服務的所有訪問?那麼,你會推動完整的實現,並使入口點成爲包裝函數,而不是將相關細節推到更接近客戶端代碼的位置。如果你想爲代碼的某些客戶而不是其他人提供某些行爲?現在你被卡住了。這只是預期使這些不可避免的權衡取而代之,並讓您的生活更輕鬆。