Coupling, Cohesion и паттерны в ФП

Зацепление (coupling) = знание одной абстракции о другой. Связность (cohesion) = насколько внутренние элементы абстракции взаимосвязаны. Цель — низкое coupling между модулями, высокая cohesion внутри. Паттерны нужны, когда есть боль; без неё — это магия без понимания.

Зацепление абстракций

Одна абстракция зацеплена на другую, если содержит вызовы, обращения к свойствам, какие-то идентификаторы, имена из других модулей. Любые знания одной абстракции о другой — это зацепление.

Без зацепления вообще ничего работать не может. Вопрос — как им управлять.

Высокое зацепление = всё сыплется

Вы вроде бы распределили решение на кучу всего, но если попытаетесь изменить логику в одном файле — возникнет проблема со всеми остальными частями.

Распределение по файлам ≠ низкое coupling. Связи могут быть скрытыми (общие константы, цепочки импортов, неявные контракты).

Внутри — связность, снаружи — нет

Cohesion: насколько связаны элементы внутри модуля. Высокая cohesion — модуль про одну вещь. Низкая — модуль про разное.

Coupling: насколько модули зависят друг от друга. Низкое coupling — модули знают друг о друге только через интерфейс/контракт.

Цель: высокая cohesion + низкое coupling. Это и SOLID, и SRP, и Hexagonal, и Clean Architecture про одно и то же.

Сначала наесться боли

Они должны годик поработать где-то. Если они сами не наелись говна, то что с ними говорить? Сначала ждёшь, чтобы наелись, тогда будешь объяснять, как лучше.

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

Книга GoF — не на JS

Открываешь книжку и видишь код на Java/C++/C#. Но на JavaScript эти товарищи не умеют писать.

Паттерны не натянуты на реалии JS. Названия в книге часто не совпадают с JS-терминами.

Ценность курса — практика с ментором

Постоянная практика написания кода при контроле человека, который знает и может направить. Другой ценности в курсе нет.

Видео и книги доступны бесплатно. Без проекта и обратной связи — почти бесполезно.

ФП и паттерны

Многие GoF-паттерны естественны в ФП:

  • Strategy → передача функции
  • Command → замыкание с захваченными аргументами
  • Observer → callback/subscribe/stream
  • Iterator → generator/iterable
  • Decorator → HOF
  • Chain of Responsibility → pipe/compose/middleware
  • State → sum-тип + функции по варианту

Mediator и Bridge через функциональный контракт

type Renderer = (nodes: Node) => Element | null;
type Mount = (render: Renderer, app: Application, opts?: Options) => void;

Bridge — связка двух иерархий контрактов (Renderer × Application). В ФП это просто типы функций.

Адаптер на функциях, не на классах

См. отдельную заметку Адаптеры asyncify, promisify, callbackify. Паттерн Adapter в ФП — это функция-обёртка, преобразующая контракт. Не нужен класс.

Цена инструкции

Если вы программисты — сделайте усилие и попытайтесь разобраться, чего стоит хотя бы каждая инструкция.

class в C++ = выделение памяти на стеке/куче, может быть POD. class в JS = объект с прототипом, hidden classes V8. Не одно и то же по стоимости.

Имена не важны в большой кодовой базе

На простом примере читаемые имена кажутся рациональными. В большой кодовой базе для вас, что gameLoop, что update, что render будут идиотскими именами.

Google Docs (после Closure Compiler) — функции с именами A, B, C, D. Понимание идёт через структуру кода, не через имя функции. Это для реверс-инженеров.

Связанные темы

Ресурсы