Насколько я понимаю, в CQRS зависимость почти всегда односторонняя: обработчики команд могут обновлять данные для чтения, но никогда не читают их.
В случае, когда нужно перед записью данных их прочитать (а нужно практически всегда), то читают из данных для записи (если нет event sourcing, а данные реляционные), или обработчик команд имеет внутреннее состояние, которое и используется для принятия решений (и обновляется при вызовах команд) — это в случае, если есть ивент сорсинг и данные для записи так просто не прочесть.
Ну и опять же, даже в случае с ивент сорсингом, можно хранить дополнительные реляционные данные (хотя это и влечет дополнительные проблемы).
CQRS, если он с командами и event sourcing-ом, имеет много больше точек оптимизации, плюс некоторые фичи, типа получения состояния на любой момент времени.
И разделение кода на кучки — это так само получается, если все это реализовывать.
ПС Разделение кода на C и Q — это, вообще-то, здравая идея, которая называется CQS (command-query separation). Этот принцип говорит, что каждый метод в приложении должен либо возвращать данные, либо их модифицировать, но модификация при чтении — это плохая идея.
redux очень похож на CQRS+event sourcing. Данные для чтения — это state, данные для записи — это бекэнд. В серверную архитектуру его, конечно, один в один не перенести, но подходы и проблемы очень похожи.
В реальных приложениях практически невозможно использовать "чистые" команды, которые не возвращают результата. Нужно будет обрабатывать ошибки, а также получать какие-то минимальные результаты, например, идентификаторы созданных сущностей и т.д.
Не стоит использовать CQRS без необходимости, его нужно применять только в самых нагруженных местах (или в системах, которые хорошо на него ложатся, например, основанных на событиях, типа приложений для такси). Реализовывать на нем CRUD — это удовольствие ниже среднего.
Только это будет не CQRS, и не будет его преимуществ. В CQRS данные для чтения имеют структуру, оптимизированную для чтения, поэтому чтение будет быстрое за счет более медленной записи. Например, вместо расчета прибыли при создании отчета (путем суммирования всех проводок) мы рассчитываем прибыль при создании каждой проводки.
В данных для записи консистентность будет строгая (как в обычном приложении). А вот между базами для чтения и для записи будет eventual consistency, то есть они будут согласованы когда-нибудь, но не прямо сейчас. Именно поэтому в обработчиках команд обычно не используется Read DB.
В CQRS данные для чтения (для запросов) могут отличаться от данных для обработки (для команд). Поэтому дублирования (и гонки) тут не будет, скорее всего.
Должна смотреть только на кубки, еще смотрит, если ты сливаешься, то выбирает тебе таких же соперников. По факту, сражение практически всегда идет на полную выкладку, по крайней мере у меня. Это стресс.
Каким образом? Мне тоже было бы интересно убрать стадию транспиляции из джаваскрипта.
Я знаю единственный вариант — это использование JSDoc комментариев, однако их функционал — это 1% от функционала Тайпскрипта (насчет Флоу не знаю). Плюс JSDoc не дружит с ES6+.
Ну вроде как иметь дополнительную информацию о типах — это лучше, чем не иметь ее вообще, разве нет? Тем более, что она опциональна и, при необходимости, легко обходится.
Не совсем правильно называть это "статическими типами", это скорее аннотации типов. Статическая типизация гарантирует (ну или пытается) отсутствие ошибок типов в рантайме. Ни флоу, ни тайпскрипт этого не гарантируют.
Старую модель необходимо переиспользовать, чтобы не грузить одни и те же данные по нескольку раз.
Вот это и есть ключевая проблема. Обновить модель по новым данным просто, если она тривиальная. Если нет — то сложно, и будут те же костыли, что и в реакте/ангуляре, только вручную.
Ну а "нетривиальных структур данных" в модели быть не должно. Гораздо удобней работать с нормализованными данными, а не с развесистым JSON.
Много чего не должно быть, однако есть. Те же лишние дивы-врапперы, появляющиеся по условию, которые вы упоминали выше. Спорить не с чем, просто уточняйте, что $mol — самый лучший фреймворк (для простых и нормализованных моделей). Замечу, однако, что в dirty checking и virtual DOM такой проблемы нет.
Пример притянут, конечно, за уши. Но суть в том, что каждый вызов создаст новый объект, и магия графа зависимостей перестанет работать и пересоздаст кусок разметки.
Для того же, чтобы она заработала, нужно хранить где-то модель, и обновлять ей свойства.
Поэтому реконциляция должна контролироваться программистом (например, как в моём примере — через создание уникальных идентификаторов)
В Реакте, если я не ошибаюсь, она контролируется через key. Это не совсем то, что у вас, но позволяет указать, когда элемент должен переиспользовать реальный ДОМ элемент (но опять же, я не уверен).
Гранулярность этого чека гораздо выше (мы чётко знаем где у нас могло что-то поменяться). И нет, вручную это проверять не надо. Вычислили новое значение, библиотека сравнива его со старым, и если зафиксировано изменение — каскад обновлений продолжается.
Понятно, что вручную обычно быстрее, т.к. учитывает специфику данных. Только вручную можно в любом фреймворке, это не интересно :)
С чего бы полное перестроение?… В случае $mol_view каждый компонент имеет ссылку на соответствующий ему элемент. ...
При пересоздании модели по новым данным ссылка будет указывать на старую модель. Напомню, я рассматривал ситуацию обновления модели новыми данными, старую модель можно переиспользовать только реализовав ручное заполнение (а это не совсем тривиально для сложных структур данных).
Построение графа, конечно, не бесплатно, но и не так уж затратно, а профита даёт много:. ...
Есть преимущества, и есть недостатки, из них: загрузка данных — это плохой сценарий, описал в предыдущих комментариях, плохая работа с проекциями (вычисляемыми моделями) — для эффективной работы проекции нужно делать наблюдаемыми и обновлять свойства при изменении.
То есть модель с графом зависимостей тяготеет к императивному стилю.
Затесалась где-то лишняя обёртка или другое имя тега и привет, полный ререндер.
Да, это так (наверное), но касается лишь случая, когда обертка добавляется или удаляется динамически. Возможно, в каком-то фреймворке есть оптимизация для этого, но имхо овчинка не стоит выделки.
При этом именно в виртуальном ДОМ наибольший потенциал для оптимизации более реалистичного случая — динамического рендера одного компонента из фиксированного набора. Если их структура похожа, то будет происходить обновление физ. ДОМ вместо пересоздания.
Насколько я понимаю, в CQRS зависимость почти всегда односторонняя: обработчики команд могут обновлять данные для чтения, но никогда не читают их.
В случае, когда нужно перед записью данных их прочитать (а нужно практически всегда), то читают из данных для записи (если нет event sourcing, а данные реляционные), или обработчик команд имеет внутреннее состояние, которое и используется для принятия решений (и обновляется при вызовах команд) — это в случае, если есть ивент сорсинг и данные для записи так просто не прочесть.
Ну и опять же, даже в случае с ивент сорсингом, можно хранить дополнительные реляционные данные (хотя это и влечет дополнительные проблемы).
БД внутри — это как раз cqrs + event sourcing, они журнал операций ведут.
АПИ CQRS систем — это отражение их eventual consistency. То есть факта, что отправив команду системе, результат нужно получать другим способом.
Ну, в общем-то, да. Можно.
CQRS, если он с командами и event sourcing-ом, имеет много больше точек оптимизации, плюс некоторые фичи, типа получения состояния на любой момент времени.
И разделение кода на кучки — это так само получается, если все это реализовывать.
ПС Разделение кода на C и Q — это, вообще-то, здравая идея, которая называется CQS (command-query separation). Этот принцип говорит, что каждый метод в приложении должен либо возвращать данные, либо их модифицировать, но модификация при чтении — это плохая идея.
Если они не отличаются, CQRS не нужен.
Смысл его в том, чтобы оптимизировать производительность приложения, выполняя расчеты (трансформации данных) во время записи (а не во время чтения).
Поэтому же CQRS подходит только приложениям, у которых интенсивность чтения намного больше интенсивности записи.
redux очень похож на CQRS+event sourcing. Данные для чтения — это state, данные для записи — это бекэнд. В серверную архитектуру его, конечно, один в один не перенести, но подходы и проблемы очень похожи.
В реальных приложениях практически невозможно использовать "чистые" команды, которые не возвращают результата. Нужно будет обрабатывать ошибки, а также получать какие-то минимальные результаты, например, идентификаторы созданных сущностей и т.д.
Только это будет не CQRS, и не будет его преимуществ. В CQRS данные для чтения имеют структуру, оптимизированную для чтения, поэтому чтение будет быстрое за счет более медленной записи. Например, вместо расчета прибыли при создании отчета (путем суммирования всех проводок) мы рассчитываем прибыль при создании каждой проводки.
В данных для записи консистентность будет строгая (как в обычном приложении). А вот между базами для чтения и для записи будет eventual consistency, то есть они будут согласованы когда-нибудь, но не прямо сейчас. Именно поэтому в обработчиках команд обычно не используется Read DB.
В CQRS данные для чтения (для запросов) могут отличаться от данных для обработки (для команд). Поэтому дублирования (и гонки) тут не будет, скорее всего.
Есть настройка
"workbench.editor.enablePreview": false, которая отключает режим просмотра.Думаю, отличается правилами вызова. Например:
Должна смотреть только на кубки, еще смотрит, если ты сливаешься, то выбирает тебе таких же соперников. По факту, сражение практически всегда идет на полную выкладку, по крайней мере у меня. Это стресс.
Каким образом? Мне тоже было бы интересно убрать стадию транспиляции из джаваскрипта.
Я знаю единственный вариант — это использование JSDoc комментариев, однако их функционал — это 1% от функционала Тайпскрипта (насчет Флоу не знаю). Плюс JSDoc не дружит с ES6+.
Ну вроде как иметь дополнительную информацию о типах — это лучше, чем не иметь ее вообще, разве нет? Тем более, что она опциональна и, при необходимости, легко обходится.
Вы не поверите...
Не совсем правильно называть это "статическими типами", это скорее аннотации типов. Статическая типизация гарантирует (ну или пытается) отсутствие ошибок типов в рантайме. Ни флоу, ни тайпскрипт этого не гарантируют.
Это, я так понимаю, издержки фреймворков с графом зависимостей (хотя не знаю, почему не использовать свойства вместо этого).
Вот это и есть ключевая проблема. Обновить модель по новым данным просто, если она тривиальная. Если нет — то сложно, и будут те же костыли, что и в реакте/ангуляре, только вручную.
Много чего не должно быть, однако есть. Те же лишние дивы-врапперы, появляющиеся по условию, которые вы упоминали выше. Спорить не с чем, просто уточняйте, что $mol — самый лучший фреймворк (для простых и нормализованных моделей). Замечу, однако, что в dirty checking и virtual DOM такой проблемы нет.
Я так понимаю, что массивы обрабатываются поэлементно, и т.к. объекты переиспользуются, то и разметка для них переиспользуется.
Я же имел ввиду нечто вроде
Пример притянут, конечно, за уши. Но суть в том, что каждый вызов создаст новый объект, и магия графа зависимостей перестанет работать и пересоздаст кусок разметки.
Для того же, чтобы она заработала, нужно хранить где-то модель, и обновлять ей свойства.
В Реакте, если я не ошибаюсь, она контролируется через
key. Это не совсем то, что у вас, но позволяет указать, когда элемент должен переиспользовать реальный ДОМ элемент (но опять же, я не уверен).Понятно, что вручную обычно быстрее, т.к. учитывает специфику данных. Только вручную можно в любом фреймворке, это не интересно :)
При пересоздании модели по новым данным ссылка будет указывать на старую модель. Напомню, я рассматривал ситуацию обновления модели новыми данными, старую модель можно переиспользовать только реализовав ручное заполнение (а это не совсем тривиально для сложных структур данных).
Есть преимущества, и есть недостатки, из них: загрузка данных — это плохой сценарий, описал в предыдущих комментариях, плохая работа с проекциями (вычисляемыми моделями) — для эффективной работы проекции нужно делать наблюдаемыми и обновлять свойства при изменении.
То есть модель с графом зависимостей тяготеет к императивному стилю.
Да, это так (наверное), но касается лишь случая, когда обертка добавляется или удаляется динамически. Возможно, в каком-то фреймворке есть оптимизация для этого, но имхо овчинка не стоит выделки.
При этом именно в виртуальном ДОМ наибольший потенциал для оптимизации более реалистичного случая — динамического рендера одного компонента из фиксированного набора. Если их структура похожа, то будет происходить обновление физ. ДОМ вместо пересоздания.
Да, для эффективности больших обновлений нужно делать "транзакционные" методы