Вы кажется в той же ловушке, что и большинство react-разработчиков. В ловушке под названием react.
Я не к тому, что реактом пользоваться не надо, нет, прекрасная штука — нежно люблю и сам использую каждый день. Нет, я к тому, что вы разрабатываете на реакте, завязываясь на сам реакт. Ну и порождаете жесткую связанность(coupling), когда она вовсе не нужна.
Почему-то DDD пока мало проникает во фронтэнд, и мало кто отделяет доменные вещи от средства отображения. Все данные, всю логику, вообще почти все можно безболезненно отделить от реакта и это будет настоящим работающим ядром приложения без всяких отображений. Можно даже наверно сказать — это будет «реализацией стейт-менеджера», который по сути «переменная + сеттер + observable». Каждый может это сделать, а если проникнуться DDD — можно сделать это очень хорошо.
Да, подход, который вы предлагаете — хорош, и мы подобным как раз пользуемся(только не в самом UI, а в службах), и конечно этот storage должен быть инкапсулирован внутри домена, чтоб coupling не повышать.
Т.е. у нас есть слой хранения данных, он доступен только слою бизнес-логики, а слой бизнес-логики уже имеет порты для того, чтобы с ним UI связался. Упрощенная схема, в жизни чуть посложнее :)
Согласен, согласен :) Но это всего-лишь перевод, который мне захотелось сделать из-за момента, в котором автор приходит к DDD и надеюсь приходит к пониманию, что инструмент(в данном случае redux) вторичен.
правильно я понимаю что state — это [условно] глобальная переменная из которой достаются собственно эти юзеры итп?
Да, верно. Redux он про то, что есть огромный объект, который хранит абсолютно все данные вашего приложения и он иммутабелен. Ну, там потом вариации с multi-store есть, но общий смысл именно таков. Главные бонусы redux — это изменение стейта через маленькие редьюсеры и EventSourcing.
В вашем примере кажется все примерно то же самое, только в другой форме и другими словами :)
и вот и для выборки и для изменений хранилища не лучше ли использовать паттерн
Это похоже на линзу. А линза — это селектор + установка значения. Т.е. похоже )
подписать заинтересованные стороны на изменение
это то, что в redux делать mapStateToProps — эта функция создает компонент-обертку над вашим компонентом, в которой каждый раз когда стейт меняется — она достает из него нужные данные и перерисовывает с ними компонент. Изменился стейт, redux знает все места, где был mapStateToProps, вызывает эти места.
а state снаружи — это какая-то внутренняя кухня видная пользователю. Нет?
Не понял вопрос…
От себя добавлю, что мы в отличии от автора оригинальной статьи у себя вообще не используем Redux, обходимся выделением предметных областей и в них в соответствии с заветами DDD уже делаем хранение, предметные службы, прикладные службы, вот это все. А с JS/TS/React это подружить уже дело техники. У нас для передачи данных из домена в компоненты работает RxJS.
Привет! Обращусь вот к этой строке: :query`https://jsonplaceholder.typicode.com/users"
Замечательно, что библиотека берет взаимодействие с сетью под капот. Однако может у меня на работе что-то не так — ux-правила требуют, чтобы при запросе показывался прелоадер, в случае ошибки корректно выводилось её содержание пользователю и дальше всякие-всякие сценарии развития ситуации.
Можно ли такое провернуть в dap? Если да — то насколько оно сложнее выглядит по сравнению с этой маркетинговой строчкой?
Приветствую! Подскажите, думали ли вы о том, как быть если нужны человеко-читаемые сообщения об ошибках в валидации?
Например для валидации om.number.and.custom(value => value > 18) — тут может быть два сообщения — или «введите», или «должен быть совершеннолетним»
Т.е. не только указать туда, где ошибка, но еще и сказать какая?
Отличная идея, сам нахожусь в поисках и экспериментах с подобными вещами.
Есть вопрос — как отлаживаете этот реактивный граф? ИМХО вся боль такой реактивности, которую я встречал в mobx например — чертовски сложно уследить, кто где как и с чем связался и куда данные летают.
Вы забыли упомянуть еще один важный слой абстракции для DDD — службы предметные и прикладные. Именно они содержат логику вашего домена или всякие прикладные штуки, проверяют инварианты, и с ними взаимодействует слой UI.
Пользуемся автоматами для управления частями отображения компонентов. Действительно, любой интерфейс можно описать конечным набором состояний, и у нас в контексте ангуляра это достаточно удобно.
Даже сделали себе небольшую библиотеку для TypeScript, которая позволяет декларативно описывать машины и их свойства — какие данные(payload) будут применены; наследовать состояния; ограничивать, в какие состояния можно переходить из текущего; навешивать коллбэки на входы-выходы из состояний. Правда её код еще есть куда совершенствовать, сделано быстро-быстро на коленке :)
Пример использования
import { IStateDeclaration, StateMachine } from 'tstate-machine';
class ButtonStateMachine extends StateMachine {
// initial state
text: string = 'do request';
diisabled: boolean = false;
// state declarations
// From what state we inherit and in what states we can transit
@StateMachine.extend(StateMachine.INTIAL, ['requestState'])
mainState: IStateDeclaration<ButtonStateMachine> = {}; // no changes relative to parent(initial) state
@StateMachine.extend('mainState', ['doneState'])
requestState: IStateDeclaration<ButtonStateMachine> = {
text: 'sending...',
disabled: true
};
@StateMachine.extend('requestState')
doneState: IStateDeclaration<ButtonStateMachine> = {
text: 'done'
// no change disabled - property inherited from requestState and has `false` value
};
// common but important actions
// states in which one we can transit from initial
@StateMachine.hide
protected get $next(): Array<string> {
return ['mainState'];
}
// remember initial state
constructor() {
super();
this.rememberInitState();
}
}
const machine = new TextStateMachine();
machine.transitTo('maintState');
machine.transitTo('requestState');
console.log(machine.text); // autocomplete works fine!
Как это?
Подскажите, для визуала - плашки, стрелочки - какое решение использовали? Или самописное?
Если не секрет — зачем большое приложение переделывать с angular на vue? Какая мотивация, как продали бизнесу эту идею и получили добро на реализацию?
Я не к тому, что реактом пользоваться не надо, нет, прекрасная штука — нежно люблю и сам использую каждый день. Нет, я к тому, что вы разрабатываете на реакте, завязываясь на сам реакт. Ну и порождаете жесткую связанность(coupling), когда она вовсе не нужна.
Почему-то DDD пока мало проникает во фронтэнд, и мало кто отделяет доменные вещи от средства отображения. Все данные, всю логику, вообще почти все можно безболезненно отделить от реакта и это будет настоящим работающим ядром приложения без всяких отображений. Можно даже наверно сказать — это будет «реализацией стейт-менеджера», который по сути «переменная + сеттер + observable». Каждый может это сделать, а если проникнуться DDD — можно сделать это очень хорошо.
Но подход действительно хороший, успехов вам!
От себя добавлю — потому что статья не про инструмент, а про идею.
Да, подход, который вы предлагаете — хорош, и мы подобным как раз пользуемся(только не в самом UI, а в службах), и конечно этот storage должен быть инкапсулирован внутри домена, чтоб coupling не повышать.
Т.е. у нас есть слой хранения данных, он доступен только слою бизнес-логики, а слой бизнес-логики уже имеет порты для того, чтобы с ним UI связался. Упрощенная схема, в жизни чуть посложнее :)
Да, верно. Redux он про то, что есть огромный объект, который хранит абсолютно все данные вашего приложения и он иммутабелен. Ну, там потом вариации с multi-store есть, но общий смысл именно таков. Главные бонусы redux — это изменение стейта через маленькие редьюсеры и EventSourcing.
В вашем примере кажется все примерно то же самое, только в другой форме и другими словами :)
Это похоже на линзу. А линза — это селектор + установка значения. Т.е. похоже )
это то, что в redux делать mapStateToProps — эта функция создает компонент-обертку над вашим компонентом, в которой каждый раз когда стейт меняется — она достает из него нужные данные и перерисовывает с ними компонент. Изменился стейт, redux знает все места, где был mapStateToProps, вызывает эти места.
Не понял вопрос…
От себя добавлю, что мы в отличии от автора оригинальной статьи у себя вообще не используем Redux, обходимся выделением предметных областей и в них в соответствии с заветами DDD уже делаем хранение, предметные службы, прикладные службы, вот это все. А с JS/TS/React это подружить уже дело техники. У нас для передачи данных из домена в компоненты работает RxJS.
:query`https://jsonplaceholder.typicode.com/users"
Замечательно, что библиотека берет взаимодействие с сетью под капот. Однако может у меня на работе что-то не так — ux-правила требуют, чтобы при запросе показывался прелоадер, в случае ошибки корректно выводилось её содержание пользователю и дальше всякие-всякие сценарии развития ситуации.
Можно ли такое провернуть в dap? Если да — то насколько оно сложнее выглядит по сравнению с этой маркетинговой строчкой?
Например для валидации om.number.and.custom(value => value > 18) — тут может быть два сообщения — или «введите», или «должен быть совершеннолетним»
Т.е. не только указать туда, где ошибка, но еще и сказать какая?
Есть вопрос — как отлаживаете этот реактивный граф? ИМХО вся боль такой реактивности, которую я встречал в mobx например — чертовски сложно уследить, кто где как и с чем связался и куда данные летают.
Ошибочка в расчетах у вас, на пи умножить забыли. И дальше все вычисления полетели…
Даже сделали себе небольшую библиотеку для TypeScript, которая позволяет декларативно описывать машины и их свойства — какие данные(payload) будут применены; наследовать состояния; ограничивать, в какие состояния можно переходить из текущего; навешивать коллбэки на входы-выходы из состояний. Правда её код еще есть куда совершенствовать, сделано быстро-быстро на коленке :)