SAM Pattern (State-Action-Model) - это новый паттерн программной инженерии, который можно использовать для отделения бизнес-логики от веб-фреймворков. Фреймворки приходят и уходят, и многие из нас пережили боль переноса большого проекта с одного фреймворка на другой.

Пару лет назад я открыл для себя шаблон SAM, и с тех пор я построил с его помощью несколько больших проектов (один на Angular2, а другой на ES6), а также несколько небольших. Я не уверен, как я мог бы убедить вас взглянуть на шаблон (я явно не специалист по маркетингу), но все, что я могу вам сказать, это то, что каждый проект, над которым я работал, был пустяком (раскрытие, шаблон составляет 100 % открытый и бесплатный, мне нечего продавать).

Одна из причин, по которой этот шаблон работает так хорошо, заключается в том, что в отличие от других парадигм программирования, SAM основан на самом надежном формализме компьютерных наук, TLA +, и поэтому он исправляет три приближения, которые мы все использовали практически с тех пор. Был изобретен первый язык программирования высокого уровня. Подробности об этих приближениях будут опубликованы в отдельном посте, но вкратце, я считаю, что когда вы исправляете эти три приближения, качество вашего кода повышается на порядки:

  1. Действия не должны изменять состояние
  2. Присвоения не эквивалентны мутациям
  3. Шаг программирования должен быть определен и реализован с точностью.

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

Шаблон 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 и связать реактивный цикл между действиями, моделью и состоянием)
- Действия, Модель »И Государство

В этот момент каждый компонент свободен от «бизнес-логики», он просто генерирует события и ждет нового набора свойств!