Вместо этого отправляйте и получайте сообщения

Резюме

В предыдущей статье мы исследовали идею передачи структурированных сообщений объектам:

const nameMessage = { type: Name };
const spot = Dog(“Spot”);
spot(nameMessage)

И мы упростили ситуацию, используя функции (с замыканиями) вместо классов:

function Dog(name) { 

  const base = Animal(name); 
  return message => message?.type === Speak 
    ? “woof” 
    : base(message);

}

Возврат сообщений

Теперь мы делаем еще один шаг вперед. Вместо того, чтобы возвращать необработанные значения из нашего объекта, вместо этого верните сообщение.

import { Cart } from "./Cart.js";
import { AddedToCart, AtCheckout, Message } from "./taxonomy.js";
import { skippingRope, yoyo } from "./catalog.js";

const cart = Cart();

// 2 yoyos
cart(Message(AddedToCart, { ...yoyo, quantity: 2 }));

// 1 skpping rope
cart(Message(AddedToCart, { ...skippingRope, quantity: 1 }));

// checkout
const cartTotals = cart(Message(AtCheckout));
console.log(cartTotals.items, "items, total cost:", cartTotals.total);

cartTotals относится к сообщению типа CartTotals, хотя мы не проверяем тип сообщения.

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

Изменение парадигм

Когда вы меняете парадигмы, вы часто достигаете этой неловкой половины пути. Вы соединяете два мира. Здесь мы ожидаем «возвратного» сообщения. Настоящее волшебство происходит, когда мы больше не различаем отправленное и полученное.

Но для этого нам нужно еще несколько кусочков головоломки, которые появятся в следующий раз.

Таксономия

Нормальное общение опирается на своего рода таксономию. _Тип_ сообщения (а не класс или метод объекта) является окончательным показателем.

В сегодняшнем примере кода мы импортируем таксономию из модуля, который выглядит следующим образом:

export const Type = Symbol("Message type");

export const AddedToCart = Symbol("Added to cart");
export const AtCheckout = Symbol("Checkout");
export const CartTotals = Symbol("Cart totals");

export const Message = (type, props) => ({

    [Type]: type,
    ...props

});

Время

Обратите внимание, что сообщения выше относятся к событиям во времени. За последние двадцать лет или около того прогресс в моделировании увеличил время. Подумайте о программировании на основе событий, DDD, моделировании событий и т. д. Время является общим отличительным фактором.

При реализации ООП я использую сообщения, которые сообщают о событии во времени. Это приводит к чистой модели, потому что именно так думают люди.

Чего нет, так это идеи «командования». Я считаю, что в этом нет необходимости. Команды допускают множество результатов. Если вместо этого объекты сообщают о том, что произошло, это однозначно.

Заключение

Мы находимся на переломном этапе на пути к реализации ООП на основе сообщений. Далее мы рассмотрим, как избавиться от необходимости «запрос-ответ»/«вызов-возврат».

https://github.com/goofballLogic/modd/tree/article-2023/articles/002-CallAndResponse