У меня в Эргономичной архитектуре есть ограничение на количество атрибутов сущностей и зависимостей операций (сервисов) с рекомендуемым значением "до 7 +/- 2".
И вот я в очередной раз наткнулся, на то, что это не я один такой
Я тут в рамках разработки Ergo AI Agent Framework пошёл снова ботанить понятия cohesion и coupling, и, в частности, пошёл читать Code Complete (aka Совершенный код).
И там на странице 143 английским по белому написано:
Be critical of classes that contain more than about seven data members
The number “7±2” has been found to be a number of discrete items a person can remember while performing other tasks (Miller 1956). If a class contains more than about seven data members, consider whether the class should be decomposed into multiple smaller classes (Riel 1996). You might err more toward the high end of 7±2 if the data members are primitive data types like integers and strings, more toward the lower end of 7±2 if the data members are complex objects.
—
Критически относитесь к классам, содержащим более чем примерно семь полей данных.
Число «7±2» было выявлено как количество отдельных элементов, которое человек способен удерживать в памяти, выполняя при этом другие задачи (Miller, 1956). Если класс содержит более примерно семи полей данных, сто́ит задуматься о том, не следует ли разложить его на несколько более мелких классов (Riel, 1996).
Можно смещаться ближе к верхней границе диапазона 7±2, если поля представлены примитивными типами данных, такими как целые числа и строки; и ближе к нижней границе, если поля являются сложными объектами.
Возможно, вы, глядя на свою MyCoreEntity с 100+ полей и MyCoreEntityService с 80+ зависимостей, думаете, что мы с Макконнеллом теоретики, которые реального кода в глаза не видели.
Но это не так:)
Может быть, и не до 7 полей, но существенно упросить MyCoreEntity можно с помощью:
1. активного выделения Value Object-ов — например, завести класс PersonName(first, middle, last) и заменить три поля на одно;
2. активного выделения аспектов сущности в отдельные сущности — например, убрать из коренной сущности пользователя поле с его подписками, на веб-пуши.
А справиться с MyCoreEntityService поможет:
1. переход от сервисов к классам-операциям (ака юз-кейсам, интеракторам) — выделение каждого метода класса сервиса в отдельный класс с одним публичным методом. С непривычки это кажется дичью — по себе знаю, мне самому так казалось 2.5 года назад — но к этому быстро привыкаешь и назад уже не хочется;
2. повышение уровня абстракции ресурсов/гейтвеев/портов — например, если у вас агрегат включает в себя блоб (картинку), то можно заменить зависимость от UsersRepo и FilesStorage на сложный/составной ресурс/порт/гейтвей, которые внутри себя держит UsersDao для работы с РСУБД и FilesStorage для работы с хранилищем блобов.
#ergo_arch@ergonomic_code #books@ergonomic_code