⚡️Извечный вопрос архитектуры: «Куда, черт возьми, положить этот метод?» 🏗
Если принципы SOLID учат нас писать чистый код, то GRASP (General Responsibility Assignment Software Patterns) отвечает за грамотное распределение ролей. Это 9 шаблонов, которые спасают проект от превращения в неподдерживаемое спагетти. 🔎Разберем их логику на классическом примере — ядре интернет-магазина 🛒
1. Информационный эксперт (Information Expert) Кто владеет данными, тот и делает работу. Кто должен считать итоговую сумму чека? Класс Order. В нем уже лежат все товары (OrderItem) и их цены. Не плодите внешние «калькуляторы»-пустышки, если нужные данные уже находятся внутри сущности.
2. Создатель (Creator) Класс А создает класс Б, если он им «владеет». Объект Order логично инициализировать внутри Customer. Именно покупатель запускает процесс оформления покупки, поэтому операция createOrder() по праву принадлежит ему.
3. Контроллер (Controller) Первый рубеж после UI. Он не работает сам, он делегирует. Юзер жмет «Оплатить». OrderController перехватывает запрос, но не лезет в базу данных. Он лишь координирует: вызывает валидацию, дергает сервис оплаты и передает результат в репозиторий.
4. Низкая связанность (Low Coupling) Классы должны знать друг о друге абсолютный минимум. Ваш Order не должен содержать сырых SQL-запросов. Он общается с абстракцией — OrderRepository. Завтра вы решите переехать с MySQL на PostgreSQL — ядро бизнес-логики этого даже не заметит.
5. Высокая зацепленность (High Cohesion) Узкая специализация. Никаких «Божественных объектов». Если класс заказа считает сумму, сохраняет себя в БД и заодно шлет email-уведомления — это провал. Разнесите это по разным сервисам. Один класс = одна зона ответственности. 6. Полиморфизм (Polymorphism) Убиваем бесконечные if/else через интерфейсы. Никаких if ($type === 'stripe') { ... }. Создаем интерфейс PaymentMethod с единым методом pay(). Системе плевать, что под капотом — карта, крипта или баланс профиля. Она просто вызывает pay().
7. Чистая выдумка (Pure Fabrication) Придумываем несуществующую сущность ради чистоты кода. В реальном мире нельзя потрогать NotificationService или Logger. Но в коде мы искусственно создаем эти классы, чтобы не засорять логику заказа отправкой SMS (тем самым сохраняя ту самую Высокую зацепленность).
8. Перенаправление (Indirection) Нужен буфер между двумя сложными системами. Заказу нужно связаться с тяжелым API банка. Чтобы не смешивать чистую бизнес-логику с токенами, таймаутами и HTTP-клиентами, мы вводим посредника — PaymentProcessor.
9. Защищенные изменения (Protected Variations) Изолируем то, что часто ломается. Курсы валют из стороннего API постоянно отваливаются? Оборачиваем вызов в интерфейс CurrencyProvider. Упал внешний сервис — мы быстро подкидываем резервную реализацию, не переписывая половину приложения.
🔥 Итог: GRASP — это не жесткие рамки, а фильтр для ваших решений. В следующий раз, когда зависнете над пустым классом, просто прогоните задачу через эти 9 пунктов.
· 24.03
Ну это база) подано хорошо 👍
0
ответить
коммент скрыт — часть юзеров считает его токсичным или некорректным
коммент удалён