burningrain / planetBot

The Unlicense
2 stars 2 forks source link

UiSharedState #7

Open burningrain opened 8 years ago

burningrain commented 8 years ago

Для согласования состояний ui-plugin-ов помимо отправки событий возникнут моменты, когда будет необходимо сохранять состояние, которое необходимо передавать между различными ui-plugin-ами. Предполагается решать эту проблему с помощью еще одного модуля (н-р, назовем его SharedState), через который будет происходить чтение/запись некоторых ui-данных.

Требования:

Решение: Это означает, что решения типа jooq не подходят. Предпочтительна разработка от бизнес-логики, а не базы. Также это означает, что по причине слабой, но зависимости ui-plugin-ов друг от друга (сильную не делаем, чтобы один плагин не вешал другой) между ними может возникать несочетаемость. Это тоже надо учитывать при разработке ui-plugin-а. 1) Новые entity будут подкладываться к SharedState через osgi-fragments, и находиться в пакете с конкретно-заданном названием 2) Накатка базы create-update происходит каждый раз при старте модуля SharedState. Модуль находит все entity в конкретном пакете и по ним накатывает бд. 3) Наружу выставляется api, которое скрывает часть работы с бд. Т.е. все entity и часть функционала для запросов.

Необходимо рассмотреть за и против в плане:

mrzo0m commented 8 years ago

А что если... Почти в шутку: A content repository is a hierarchical content store with support for structured and unstructured content, full text search, versioning, transactions, observation, and more. Я про JSR Jackrabbit

burningrain commented 8 years ago

Опиши, плиз, где тогда какая логика будет располагаться. Подробно.

mrzo0m commented 8 years ago

В этом варианте логика не предполагается, тут только состояние атрибут UI. Без возможности фильтрации. UI State -> POJO + ID -> STORE ; ID -> STORE -> POJO -> UI State

burningrain commented 8 years ago

Есть модуль работы с данными различных ui компонент - UiSharedState. Все ui-plugin-ы пишут в одну базу для упрощения. Каждый модуль может заюзать данные из другого модуля. Имеем: 1) модуль UiSharedState, который поставляет api для работы с собой 2) ui-plugin, который инжектит сервис из UiSharedState и использует апи. То есть плагин=клиент, UiSharedState=внешний сервис. Теперь вот прям подробнее погружаемся.

interface UiSharedState {
    <E> void create(E entity);
    <E> void update(E entity);
    <E> void delete(E entity);
    <ID, E> void get(ID id, Class<E> clazz);
}

Делаю компонент, который задает цветовые схемы. Он умеет только задавать цвет, и все. На ui это выглядит как в старике. Есть список каких-то игроков и инструмент выбора цвета. Ок, создал сущность ColorScheme.

class ColorScheme implements Serializable {    
    // Long id; а что насчет id? Аннотация? Наследование от конкретного класса?

    Map<Player, Color> scheme;    
    // get, set
}

Теперь у меня есть ui-plugin, который умеет сохранять цвета.

class PluginExample implements IuiPlugin {

    @Component
    UiSharedState uiSharedState;

    public void doSomething(){
        ColorScheme cs = getColorScheme();
        uiSharedState.create(cs);
    }

    // представляем, что остальное есть
}

Круто! Теперь хочу дать возможность пользователю через этот же компонент задать цвета игрокам. Задумаемся, можем ли мы запустить N игр одновременно? Решено, что можем. Значит этот плагин должен знать какие игры запущены и уметь определять текущую расцветку игроков. Говоря проще имеем кучу связей 1-к-1 игра-цветовая схема. Как оно тогда выглядит, получение цветовой схемы?

class PluginExample implements IuiPlugin {

    @Component
    UiSharedState uiSharedState;

    public void getColorSchemeAndDoSomething(){
        Long gameId = getGameId(); // откуда-то получили. Пофигу откуда.
        Game game = uiSharedState.get(gameId, Game.class);
        Long colorSchemeId = game.getColorSchemeId();
        ColorScheme = uiSharedState.get(colorSchemeId, ColorScheme.class);
        // че-то делаем дальше
    }

    // представляем, что остальное есть
}
burningrain commented 8 years ago

Понятно, что это неудобно и далеко мы так не уедем. Поэтому какие варианты? 1) Тащить в ui-plugin функционал в духе Criteria api для фреймворка, с которым будет работать UiSharedState. Теряется изолированность. 2) Пишутся свои билдеры запросов типа Criteria api. UiSharedState умеет преобразовывать запрос из своего билдера в запрос фреймворка, который работает с бд. Этот вариант однозначно чище, однако стоит ли заморачиваться? Еще транзакции. Хотя они как бы нам и не особо играют роли, на уровне даохи проблему не решить. Проблему можно решить только в ui-plugin-е.

burningrain commented 8 years ago

Возвращаемся теперь к баранам:

Вот именно ответы на эти вопросы я и спрашивал, когда просил описать подробнее. Не думаю, что решение с кроликом хуже или лучше, просто там есть куча функционала, который нам не нужен в принципе. В любом случае, необходимо иметь конкретные ответы на данные вопросы при проектировании решения данной таски.