SAM Pattern (State-Action-Model) - это новый паттерн программной инженерии, который можно использовать для отделения бизнес-логики от веб-фреймворков. Фреймворки приходят и уходят, и многие из нас пережили боль переноса большого проекта с одного фреймворка на другой.
Пару лет назад я открыл для себя шаблон SAM, и с тех пор я построил с его помощью несколько больших проектов (один на Angular2, а другой на ES6), а также несколько небольших. Я не уверен, как я мог бы убедить вас взглянуть на шаблон (я явно не специалист по маркетингу), но все, что я могу вам сказать, это то, что каждый проект, над которым я работал, был пустяком (раскрытие, шаблон составляет 100 % открытый и бесплатный, мне нечего продавать).
Одна из причин, по которой этот шаблон работает так хорошо, заключается в том, что в отличие от других парадигм программирования, SAM основан на самом надежном формализме компьютерных наук, TLA +, и поэтому он исправляет три приближения, которые мы все использовали практически с тех пор. Был изобретен первый язык программирования высокого уровня. Подробности об этих приближениях будут опубликованы в отдельном посте, но вкратце, я считаю, что когда вы исправляете эти три приближения, качество вашего кода повышается на порядки:
- Действия не должны изменять состояние
- Присвоения не эквивалентны мутациям
- Шаг программирования должен быть определен и реализован с точностью.
Большая часть кода, который я вижу, нарушает эти три принципа. Обработчики событий спешат изменить состояние приложения, мутации разбросаны по всему коду в виде присваиваний, и нет конкретного строительного блока, который мы могли бы идентифицировать как шаг программирования, подойдет любая строка кода.
Шаблон SAM очень легко внедрить: это простой разложение обработчиков событий. Все, что вам нужно сделать, это разделить код в ваших обработчиках событий на три сегмента:
- действия, которые преобразуют события в предложения по изменению состояния приложения (но не изменяют его сами)
- модель, которая оценивает предложение и принимает (или отклоняет его), это модель, которая изменяет состояние приложения в виде единого дерева состояний
- функция, которую мы будем называть функцией «состояние», которая вычисляет представление состояния на основе значений свойств модели и делает его доступным для любого компонента, которому требуется доступ к «состоянию приложения».
Ни одна строка кода не может получить доступ к значениям свойств модели (то есть к состоянию приложения). Компоненты могут получить доступ только к вычисленному снимку: представлению состояния.
Цикл (действие, модель, состояние) - это этап программирования.
Вот и все, мы можем резюмировать шаблон в одной строке кода:
stateRepresentation = Состояние (Модель. настоящее (Действие (событие))). затем (вздремнуть)
nap - это функция (предикат следующего действия), которая вычисляет, есть ли в представлении состояния какое-либо действие, которое необходимо запустить, в противном случае, когда действий нет, обработчик событий дождитесь следующего события (пользовательского или системного).
SAM не извиняется за мутацию состояния приложения, которая лежит в основе шаблона.
Давайте рассмотрим несколько примеров, чтобы проиллюстрировать, как реализуется SAM, один с ES6 в его простейшей форме, а другой с Angular.
Счетчик будет выглядеть так:
Давайте теперь рассмотрим более реалистичный пример, используя Шаблон SB Admin (Angular4, Bootstrap4).
Я не большой поклонник шаблонов, но Angular действительно упрощает использование модели программирования публикации / подписки для передачи представления состояния отдельным компонентам. В этом посте мы сосредоточимся на компоненте диаграмм.
Первым шагом к «включению SAM» компонента является подписка на набор свойств из представления состояния (см. Конструктор). Каждый раз, когда новое представление состояния будет генерироваться функцией State, если есть какие-либо соответствующие аспекты в наборе «dashboard.charData», компонент, любой компонент, который подписывается на этот набор, будет уведомлен, и Angular сделает это волшебство и выполнит необходимые изменения в пользовательском интерфейсе.
Метод bind «привязывает» свойства представления состояния к свойствам компонента.
Теперь вам нужно связать события компонента с действиями SAM. Опять же, это не может быть проще, например, вот как мы связываем событие ngOnInit с соответствующим действием initCharts:
Элемент State - единственный элемент шаблона, взаимодействующий с компонентами Angular. Как только действие отправлено, оно просто выполняет соответствующий цикл SAM: действие / модель / состояние = ›компонент.
В этот момент 100% логики вашего приложения находится в шаблоне SAM!
Давайте посмотрим, как шаблон SAM «встроен» в Angular.
Шаг 1. Обеспечьте монтирование действий в index.hmtl.
Шаг 2. Добавьте поставщиков SAM (SamFactory и State), а также любые службы, которые может использовать логика вашего приложения.
Шаг 3: добавьте свои действия. Обычно я использую простое сопоставление «намерений», чтобы связать события с действиями, но это не обязательно.
Шаг 4: добавьте модели «акцепторов». Акцепторы изменяют состояние приложения. Обычно я вызываю акцепт в зависимости от содержания предложения. Это создает приятную развязку между действием и моделью и обеспечивает связь «многие ко многим» между действиями и акцепторами (то есть одно действие может запускать несколько акцепторов, и, конечно же, несколько действий могут запускать один и тот же акцептор).
Шаг 5: после того, как модель изменила шаг приложения, мы готовы к последнему шагу шаблона - представлению состояния. В этом случае представление состояния довольно простое, мы извлекаем значение свойства model.charts и передаем его компоненту charts. В этот момент Angular берет на себя и завершает рендеринг:
Вот и все. Код поставляется с четырьмя классами, которые вы можете использовать повторно:
- SamFactory (цель которого - создать экземпляр SAM и связать реактивный цикл между действиями, моделью и состоянием)
- Действия, Модель »И Государство
В этот момент каждый компонент свободен от «бизнес-логики», он просто генерирует события и ждет нового набора свойств!