什么是构建模式的clojure方式?

时间:2012-09-28 04:39:51

标签: design-patterns clojure builder

我们通常在java中使用构建器模式,如下所示:

UserBuilder userBuilder = new UserBuilder();
User John = userBuiler.setName("John")
                      .setPassword("1234")
                      .isVip(true)
                      .visableByPublic(false)
                      .build();

某些属性具有默认值,而有些属性则没有。

在地图中传递属性可能是一种解决方案,但它会使参数真正变长:

(def john (make-user {:name "John" :pass "1234" :vip true :visible false}))

所以,我的问题是,有没有一种优雅的方法来实现这一目标?

5 个答案:

答案 0 :(得分:9)

如果要构造一些clojure结构,可以在函数参数中使用解构模式。然后,您将完成类似的事情。

(defn make-user [& {:keys [name pass vip visible]}]
  ; Here name, pass, vip and visible are regular variables
  ; Do what you want with them
)

(def user (make-user :name "Name" :pass "Pass" :vip false :visible true))

我怀疑你能用比这更少的代码做点什么。

如果你想构建Java对象(使用它的setter),你可以使用Nicolas建议的方法。

答案 1 :(得分:4)

我通常会通过地图传递属性 - 这样做没有真正的问题,因为属性映射实际上只是make-user函数的一个参数。你也可以在make-user里面做一些很好的东西,比如在默认属性中合并。

如果你真的想用构建器模式构建这样的地图,可以使用线程宏来完成,如下所示:

(def john 
  (-> {}
    (assoc :name "John")
    (assoc :pass "1234")
    (assoc :vip true)
    (assoc :visible false)
    make-user))

答案 2 :(得分:4)

重写

(def john (make-user {:name "John" :pass "1234" :vip true :visible false}))

分为多行:

(def john (make-user {:name "John" 
                      :pass "1234" 
                      :vip true 
                      :visible false}))

答案 3 :(得分:2)

一种简单的方法是使用doto宏:

以下是使用某些值填充数组列表的示例:

(def al (doto (java.util.ArrayList.) (.add 11) (.add 3)(.add 7)))

Stuart关于如何在Swing中使用doto some perfect examples。 这里有一个小组:

(doto (JPanel.)
            (.setOpaque true)
            (.add label)
            (.add button))

这里有一个框架:

(doto (JFrame. "Counter App")
  (.setContentPane panel)
  (.setSize 300 100)
  (.setVisible true))

答案 4 :(得分:0)

为了完整性,没有人提到defrecord自动为您提供"构建器功能"

<div>
    <kendo-grid options="mainGridOptions" k-data-source="gridData">
    </kendo-grid>
</div>