Clojure Model-View-Controller (MVC) design

感情迁移 提交于 2019-12-03 02:51:56
Arthur Ulfeldt

A lot of the design patterns from the java MVC world get a bit silly when you have first order functions, macroes (code-as-data), and concurrent persistent data structures. for instance the "observer pattern" is basically just an agent with some watches set. It goes from being a pattern to a function call.

if you store the state (model) in a ref or agent and make your view a function (in the functional programming sense of the word) that displays that state; while making your controller a function (again in the FP sense of the word) that produces a new state given the old state and some new input then the MVC model falls out very nicely.

it s bit dated, but Stuart Sierra's grid bag layout post really helped me get started in this area.

In Clojure you can certainly do MVC, but I'd suggest implementing it using watches on Clojure references.

Code would be something like:

; define the model as an immutable structure stored in a ref
(def model (ref (create-my-model)))

; function to update the UI when the model changes
(def update-function [old-model new-model]
  (do-whatevever-updates old-model new-model))

; add a watch to the model to call update-function when a change happens
(add-watch model :on-update
  (fn [key reference old-state new-state]
    (if (not= old-state new-state)
      (update-function old-state new-state))))

Also if you are building a GUI in Clojure, it may well be worth taking a look at some of the existing Swing library wrappers, e.g.:

  • Clarity - has a nice DSL for defining UI elements
  • Seesaw - possibly the most mature wrapper for Swing
  • clj-swing
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!