flatgui: reactive gui toolkit implemented in clojure

30
Reactive GUI Implemented in Clojure Denys Lebediev

Upload: denyslebediev

Post on 16-Jul-2015

75 views

Category:

Software


2 download

TRANSCRIPT

Page 1: FlatGUI: Reactive GUI Toolkit Implemented in Clojure

Reactive GUI Implemented in Clojure

Denys Lebediev

Page 2: FlatGUI: Reactive GUI Toolkit Implemented in Clojure

Quick background

Page 3: FlatGUI: Reactive GUI Toolkit Implemented in Clojure

«Традиционный» подход

• Шаблон Event-Listener

• Модель данных виджета мутируема

– Example: isPressed/setPressed

• Состояние виджета мутируемо

– Example: isEnabled/setEnabled

Page 4: FlatGUI: Reactive GUI Toolkit Implemented in Clojure

Традиционный подход: проблемы

• Сложные GUI контейнеры (диалоги, мастера, и т.д.) бывает трудно:

– Разрабатывать

– Поддерживать

– Расширять

• Почему?

Page 5: FlatGUI: Reactive GUI Toolkit Implemented in Clojure

Традиционный подход: проблемы

• Таким способом мы прячем логику

Page 6: FlatGUI: Reactive GUI Toolkit Implemented in Clojure

Традиционный подход: проблемы

• Таким способом мы прячем логику

– Пример: если кнопка стала неактивной, то может быть неясно почему она так сделала, и когда, при каких условиях с ней это происходит

Page 7: FlatGUI: Reactive GUI Toolkit Implemented in Clojure

Традиционный подход: проблемы

• Таким способом мы прячем логику

– Пример: если кнопка стала неактивной, то может быть неясно почему она так сделала, и когда, при каких условиях с ней это происходит

• А также, рассредоточиваем логику

Page 8: FlatGUI: Reactive GUI Toolkit Implemented in Clojure

Традиционный подход: проблемы

• Таким способом мы прячем логику

– Пример: если кнопка стала неактивной, то может быть неясно почему она так сделала, и когда, при каких условиях с ней это происходит

• А также, рассредоточиваем логику

– Причины произошедшего с кнопкой могут быть разбросаны по разным местам исходного кода приложения

Page 9: FlatGUI: Reactive GUI Toolkit Implemented in Clojure

Традиционный подход: проблемы

• Таким способом мы прячем логику

– Пример: если кнопка стала неактивной, то может быть неясно почему она так сделала, и когда, при каких условиях с ней это происходит

• А также, рассредоточиваем логику

– Причины произошедшего с кнопкой могут быть разбросаны по разным местам исходного кода приложения

– Тем более, со временем

Page 10: FlatGUI: Reactive GUI Toolkit Implemented in Clojure

Традиционный подход: проблемы

• Incidental complexity– В результате мы пишем код, несущественный

для исходной задачи (домена)

– Тратим ресурсы на то чтобы решить когда

– А также, на то чтобы разобраться в решениях коллег

• Трудности автоматизированного тестирования– На основе робота

Page 11: FlatGUI: Reactive GUI Toolkit Implemented in Clojure

Есть другой способ

• Библиотека берёт часть рутины на себя

– Однажды реализована и оттестирована

– Стремимся к тому, чтобы разработчик концентрировался на своей задаче (домене)

Page 12: FlatGUI: Reactive GUI Toolkit Implemented in Clojure

Есть другой способ

• Библиотека берёт часть рутины на себя

– Однажды реализована и оттестирована

– Стремимся к тому, чтобы разработчик концентрировался на своей задаче (домене)

• Вся логика одного свойства в одном месте

Page 13: FlatGUI: Reactive GUI Toolkit Implemented in Clojure

Есть другой способ

• Библиотека берёт часть рутины на себя

– Однажды реализована и оттестирована

– Стремимся к тому, чтобы разработчик концентрировался на своей задаче (домене)

• Вся логика одного свойства в одном месте

• Обычные юнит-тесты для кода, который управляет моделью и состоянием виджета

Page 14: FlatGUI: Reactive GUI Toolkit Implemented in Clojure

Hello world with FlatGUI

(defcomponent checkbox :say-hello {:text "Greeting"})

(def nogreeting-text "Greeting not provided")

(def greeting-text "Hello, world!")

(defevolverfn greeting-evolver :text

(if (get-property [:say-hello] :pressed)

greeting-text

nogreeting-text))

(defcomponent label :greeting-label

{:text nogreeting-text

:evolvers {:text greeting-evolver}})

Page 15: FlatGUI: Reactive GUI Toolkit Implemented in Clojure

Hello world with FlatGUI

(defcomponent checkbox :say-hello {:text "Greeting"})

(def nogreeting-text "Greeting not provided")

(def greeting-text "Hello, world!")

(defevolverfn greeting-evolver :text

(if (get-property [:say-hello] :pressed)

greeting-text

nogreeting-text))

(defcomponent label :greeting-label

{:text nogreeting-text

:evolvers {:text greeting-evolver}})

Page 16: FlatGUI: Reactive GUI Toolkit Implemented in Clojure

Hello world with FlatGUI

(defcomponent checkbox :say-hello {:text "Greeting"})

(def nogreeting-text "Greeting not provided")

(def greeting-text "Hello, world!")

(defevolverfn greeting-evolver :text

(if (get-property [:say-hello] :pressed)

greeting-text

nogreeting-text))

(defcomponent label :greeting-label

{:text nogreeting-text

:evolvers {:text greeting-evolver}})

Page 17: FlatGUI: Reactive GUI Toolkit Implemented in Clojure

Чем это отличается?

• greeting-evolver является единым место для всей логики свойства :text лейбла

Page 18: FlatGUI: Reactive GUI Toolkit Implemented in Clojure

Чем это отличается?

• greeting-evolver является единым местом для всей логики свойства :text лейбла

• Эта функция содержит логику, не рутину

Page 19: FlatGUI: Reactive GUI Toolkit Implemented in Clojure

Чем это отличается?

• greeting-evolver является единым место для всей логики свойства :text лейбла

• Эта функция содержит логику, не рутину

• Эту функцию легко отлаживать

Page 20: FlatGUI: Reactive GUI Toolkit Implemented in Clojure

Чем это отличается?

• greeting-evolver является единым место для всей логики свойства :text лейбла

• Эта функция содержит логику, не рутину

• Эту функцию легко отлаживать

• Эту функцию легко покрыть юнит-тестами

Page 21: FlatGUI: Reactive GUI Toolkit Implemented in Clojure

Чем это отличается?

• greeting-evolver является единым место для всей логики свойства :text лейбла

• Эта функция содержит логику, не рутину

• Эту функцию легко отлаживать

• Эту функцию легко покрыть юнит-тестами

• Разработчику не нужно решать когда её вызвать

Page 22: FlatGUI: Reactive GUI Toolkit Implemented in Clojure

Чем это отличается?

• greeting-evolver является единым место для всей логики свойства :text лейбла

• Эта функция содержит логику, не рутину

• Эту функцию легко отлаживать

• Эту функцию легко покрыть юнит-тестами

• Разработчику не нужно решать когда её вызвать

• Разработчику не нужно её вызывать

Page 23: FlatGUI: Reactive GUI Toolkit Implemented in Clojure

Чем это отличается?

• Реактивный движок берёт эти заботы на себя

– С каждым новым GUI контейнером, как бы ни отличалась его предметная область, по сути мы решаем одни и те же задачи

– Однажды реализованный движок прячет их под капот

– А также, покрывает тестами

Page 24: FlatGUI: Reactive GUI Toolkit Implemented in Clojure

FlatGUI architecture

Page 25: FlatGUI: Reactive GUI Toolkit Implemented in Clojure

Engine performs state transition

Page 26: FlatGUI: Reactive GUI Toolkit Implemented in Clojure

Option to run as RIA

Page 27: FlatGUI: Reactive GUI Toolkit Implemented in Clojure

Setup collaboration sessions

Page 28: FlatGUI: Reactive GUI Toolkit Implemented in Clojure

Опыт использования Clojure

• Макросы здесь очень кстати

– Создание типов и объектов виджетов, property evolver -функций

– Layout management: “ниже” “справа” и т.п.

– Возможностей IDE ещё немного недостаточно

• Было много профилирования

– Появилось немного не-идиоматического Clojure кода

Page 29: FlatGUI: Reactive GUI Toolkit Implemented in Clojure

Что дальше?

• Focus-management – первое, чего не хватает, и что скоро появится

• Оптимизации для сетевого варианта

• Писать тесты и документацию

• Доводить имеющиеся виджеты и делать новые

• Пожелания приветствуются

• Участие приветствуется