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. Понимание идёт через структуру кода, не через имя функции. Это для реверс-инженеров.
Связанные темы
Ресурсы
- Шаблоны разработки: PlXh9l04Uz8
- Беседа GRASP/SOLID/GoF: LJJpbFcmKQs
- Clean Code и перформанс: vGm-FPhPwcs