对于大部分 Clojure 流行的库, 大致有如下3种方法可以让开发者导入自己的配置:
显式: 函数参数
以 Github 的 Clojure Client Raynes/tentacles 为例.
我们需要拿到一些配置(诸如key, secret, token之类), 传入函数以此获得足够的权限调用API.
其实现:
隐式: 动态作用域
以 Memcached Client soasme/spymemcat 为例
在使用 Client 前, 肯定需要配置好 Memcached 实例的 host, port.
开发者在使用的时候, 可以通过 Clojure 的特性: 动态作用域 binding 进行设置:
实现:
显式传参写法简单易读, 但调用稍微麻烦;
隐式作用域调用参数少, 但暴露了内部的数据实现;
到底是显式传参还是动态绑定更好, 没有定论.
大概由于第二种方法比较省参数, 社区似乎比较偏爱这一种.
混合式
混合式同时提供了上面两种风格的API. 来看下 Clojure-clutch/clutch 的使用:
这个库照顾了两种风格的API, 同一个实现都提供了两种风格的调用方法.
从实现上看, 大致是这么做的:
实现混合式之1
首先, 需要给出显式传参风格的接口, 配置作为第一个参数传入.
即 [db id ...]
.
其次, 提供动态作用域的绑定接口(隐藏实现细节, 开发者只需传入配置即可, 无需了解这个假定的*database*
)
再次, 定制中间层:
最后, 套上中间层:
实现混合式之2
先给出显式传参的接口, 不过这次给它标记上 :dynamic
元数据:
再使用 partial 传参:
也就好了.
以上两套拳打下来, 都能做到刚中有柔, 柔中有刚, 刚柔并济, 早晨的辣肉松面包挺好吃的:
Inspired by À la carte configuration in Clojure APIs.