mik*_*era 14 encapsulation abstraction clojure data-structures
我正在Clojure中开发一个具有多个子结构的复杂数据结构.
我知道我会想要随着时间推移扩展这个结构,有时可能想要改变内部结构而不会破坏数据结构的不同用户(例如我可能想要将一个向量更改为一个hashmap,添加某种索引出于性能原因的结构,或者包含Java类型)
我目前的想法是:
我认为这会有效,但我担心它开始看起来像很多"胶水"代码.它也可能反映了我对面向对象方法的更多熟悉.
在Clojure中推荐的方法是什么?
Mic*_*zyk 11
我认为这deftype可能是要走的路,但是我会通过访问器方法.相反,看看clojure.lang.ILookup和clojure.lang.Associative; 这些接口,如果你为你的类型实现它们,将允许你使用get/ get-in和assoc/ assoc-in,提供一个更通用的解决方案(不仅你能够改变底层实现,但也许也可以使用建立在顶层的功能Clojure的标准集合库来操纵你的结构).
有几点需要注意:
你或许应该开始defrecord使用get,assoc及公司与标准defrecord的实现ILookup,Associative,IPersistentMap和java.util.Map.你可能会用它走很长的路.
如果/当这些不再足够时,请查看emit-defrecord(core_deftype.cljClojure源中定义的私有函数)的源代码.它非常复杂,但它可以让您了解可能需要实现的内容.
既不是deftype也没有defrecord为你定义任何工厂功能,但你应该自己做.完整性检查进入这些功能(和/或相应的测试).
概念上更复杂的操作当然非常适合构建在get&Co.基础上的协议功能.
哦,并gvec.clj在Clojure的源代码中deftype查看一些使用的一些严肃的数据结构代码可能看起来像的例子.这里的复杂性与您在问题中描述的内容有所不同,但它仍然是Clojure中当前可供公众使用的少数自定义数据结构编程示例之一(当然它也是优质代码).
当然,这正是我的直觉告诉我的.我不确定在这个阶段是否存在很多已确定的习语,deftype实际上并没有被释放的所有内容.:-)