JavaFX и Clojure: привязка наблюдаемых к неизменным объектам

Я пытался выяснить подход, чтобы позволить JavaFX TableView (или любому другому JavaFX) представлять некоторые данные Clojure и позволить пользователю манипулировать данными через графический интерфейс.

Для этого обсуждения давайте предположим, что у меня есть список / вектор карт, то есть что-то вроде [{:col1 "happy1" :col2 "sad1"} {:col1 "happy2" :col2 "sad2"}] и я хочу, чтобы это отображалось в графической таблице следующим образом:

mykey1      mykey2
------------------
happy1      sad1
happy2      sad2

Довольно просто. Это было сделано миллиард раз в мировой истории.

Проблема заключается в том, что TableView настаивает на использовании ObservableList и т. Д., Что по сути является изменчивой вещью, как и все Observables в JavaFX. Это отлично подходит для поддержания таблицы в актуальном состоянии, а в изменчивой модели она также отлично подходит для того, чтобы позволить пользователю напрямую манипулировать данными через графический интерфейс. Я не эксперт, но в этом случае кажется, что JavaFX хочет, чтобы объект GUI действительно содержал реальные данные. Это кажется смешным (не ха-ха) для меня. Поддержание моей собственной модели и связи между GUI и моделью через некоторый API или интерфейс также подразумевает, что я поддерживаю данные в двух местах: в моей собственной модели и в GUI. Это правильный способ делать вещи? Возможно, это нормально, поскольку графический интерфейс отображает лишь небольшую часть от общих данных, и он позволяет моим модельным данным быть просто обычными модельными данными, а не экземпляром какого-либо типа, производного от Java.

Таким образом, это приводит к следующим трем общим вопросам при попытке установить графический интерфейс для модели без состояния / неизменности:

  1. Как модель может быть действительно неизменной, если графический интерфейс обязательно позволяет вам что-то менять? Я имею в виду какой-то инструмент проектирования, редактор и т. Д., Где пользователь явно меняет все вокруг. Например, LightTable - это редактор, но история в том, что он основан на неизменных данных. Как это может быть? Я не заинтересован в FRP для этого обсуждения.

  2. Предполагая, что на каком-то уровне есть хотя бы один Atom или другой изменяемый тип Clojure (ref/var/agent/etc) (будь то одиночный Atom содержит всю базу данных проектирования в памяти или является ли база данных проектирования неизменным списком изменяемых Atoms), какая из моделей [MVP, MCP, MVVM и т. д.] лучше всего подходит для этого типа творения?

  3. JavaFX замусорил иерархию классов всеми возможными вариантами интерфейса Observable ( http://docs.oracle.com/javafx/2/api/javafx/beans/Observable.html) такими драгоценными камнями, как Observable[whatever]Valueв том числе например ObservableMap а также ObservableMapValue, а затем десятки десятков реализующих классов, таких как IntegerProperty а также SimpleIntegerProperty... Боже! WTF?. Предполагая, что я должен создать несколько объектов Clojure (defrecordи т. д.) и реализовать некоторые из Observable методы интерфейса на моих в основном неизменных объектах, могу ли я просто придерживаться Observableили я должен реализовать каждый из них до конечного узла, т.е. ObservableIntegerValue, так далее.?

Каков правильный подход высокого уровня? Поддерживать один атом верхнего уровня, который заменяется каждый раз, когда пользователь изменяет значение? Поддерживать тысячу атомов низкого уровня? Позвольте моим значениям жить как JavaFX Observables и забыть о структурах данных Clojure? Реализовать мой собственный набор Observables в Clojure с использованием некоторого reify/proxy/gen-class, но реализовать их как неизменяемые, которые заменяются каждый раз, когда вносятся изменения? Есть ли необходимость или место для Clojure? add-watch функционировать? Я бы очень предпочел, чтобы мои данные были просто обычными данными в Clojure, а не "типом" или реализацией интерфейса чего-либо. Целое число должно быть целым числом и т. Д.

Спасибо

1 ответ

Я бы добавил часы к атому, а затем обновил бы вашу наблюдаемую на основе различий. http://clojuredocs.org/clojure.core/add-watch

Другие вопросы по тегам