【发布时间】:2017-07-06 14:59:46
【问题描述】:
在 Clojure(script) 中,您使用 deftype 和 defrecord 定义编程结构。我们希望我们的构造每个都有一个特定的、明确定义的目的。我们没有将任何一个构造演变成一个单一的功能齐全的东西,而是选择分离职责。装饰器(例如包装其他数据结构的数据结构)对此很有用。
例如,您有一个记录器构造。您可以使用装饰器添加时间戳作为功能。您稍后添加警报支持人员蜂鸣器作为另一个装饰器。理论上,我们可以通过这种方式对任意数量的特征进行分层。我们的配置文件清楚地确定了包含哪些功能。
如果我们的 logger 实现了一个 3 方法 Logging 协议并且每个装饰器只增加一个,那么您仍然必须在每个装饰器上实现其他两个方法来维护合同 API。这些无添加的实现只是将消息传递到链中。这有点尴尬。
构造的 api 越丰富,问题就越严重。考虑一个实现了一些协议的构造,以及装饰处理 12 个左右方法的东西所需的工作。
您是否发现了一种机制、宏或技术来克服这个问题?
【问题讨论】:
-
一种用于将数据结构与其他数据结构封装在一起的技术,或者实际上将函数与其他函数封装在一起的技术称为“中间件”。通常人们会通过 Ring:github.com/ring-clojure/ring/wiki/Concepts.
-
中间件很棒,但根据我的经验,它是为功能而设计的(例如,只处理一种消息的合约)。当你有一个可能包含多种方法的构造(例如协议)时,我提到的复杂性就出现了。问题是:如何为支持多种方法的结构构建中间件,而不必在每一层都充实每个方法?
-
中间件正是装饰器模式,应用于函数。这个问题是关于如何将其应用于多个功能的“捆绑”。
标签: clojure decorator clojurescript