我正在编写一个简单的服务来检索来自不同来源(instagram,flickr,google)的图片
目前,每个服务都在一个单独的.clj
文件中提供,该文件具有一系列常用功能和特定功能。
我正在考虑为此引入协议ImageService
,每个特定服务都将实现该协议。这样我们就可以在协议级别添加文档并重用常用方法。
使用协议解决此类问题的利弊是什么?我们如何为服务创建具体实施:deftype
,defrecord
或reify
?什么是clojure中的惯用法?
答案 0 :(得分:0)
我们公司在使用外部服务的协议方面取得了很大成功,就像您所描述的那样。协议很好,因为它们允许您以单一的不可知方式编写调用代码,并且还可以进行依赖注入以便于测试(使用协议的模拟实现)。我遇到的协议的主要缺点是你不能拥有(共享)默认实现,否则我对它们非常满意。
deftype
和defrecord
不同in several ways,实际上最显着的区别是使用defrecord生成的类型也可以像地图一样:
(defrecord Foo [bar])
(->Foo 1) ; or (Foo. 1)
; => #user.Foo{:bar 1}
(assoc (Foo. 1) :norf 2)
; => #user.Foo{:bar 1, :norf 2}
如果您需要此行为,请由您决定。 reify
只是创建一个协议的“匿名”实现,我们倾向于不使用它,而是使用像
(deftype MyService [args...])
; Our own public constructor
(defn ->my-service [config]
(->MyService (parse-config config)))
; etc ...