Как менять код соблюдая второй принцип SOLID?
Покажу простой rest api псевдо код:
class UserController: public function all(): array return $this->userService->all()->toArray(); public function single($id): array return $this->userService->single($id)->toArray(); class UserService: public function all(): UserServiceDTOCollection $users = $this->repo->all(); # convert UserRepositoryDTOCollection -> UserServiceDTOCollection $users->convert(UserServiceDTOCollection::class); return $users; public function single($id): UserServiceDTO $user = $this->repo->single($id); # convert UserRepositoryDTO-> UserServiceDTO $user->convert(UserServiceDTO::class); return $user class UserRepository: public function all(): UserRepositoryDTOCollection ... public function single($id): UserRepositoryDTO ... |
class UserController: public function all(): array return $this->userService->all()->toArray(); public function single($id): array return $this->userService->single($id)->toArray(); class UserService: public function all(): UserServiceDTOCollection $users = $this->repo->all(); # convert UserRepositoryDTOCollection -> UserServiceDTOCollection $users->convert(UserServiceDTOCollection::class); return $users; public function single($id): UserServiceDTO $user = $this->repo->single($id); # convert UserRepositoryDTO-> UserServiceDTO $user->convert(UserServiceDTO::class); return $user class UserRepository: public function all(): UserRepositoryDTOCollection ... public function single($id): UserRepositoryDTO ...
Вот мой код, если кратно тут 3 слоя: UserController, UserService, UserRepository, все отделены DTO'шками.
1. Как по принципам солид добавлять/удалять/менять контроллеры?
Как вижу я:
Добавлять/изменять - UserController2 extends UserController и DI:container(UserControllerInterface::class, new UserController2)
Удалять - тут уже в route.php просто удалять путь
2. Если поступила задача юзеру добавить новое поле, например Avatar, то как это сделать?
Как я вижу:
1. UserResitoryWithAvatar extends UserRepository
2. UserRepositoryAvatarDTO extends UserRepositoryDTO
3. UserRepositoryAvatarDTOCollection extends UserRepositoryDTOCollection,
4. UserService доваляют новый метод allWithAvatar():UserServiceWithAvatarDTOCollection
5. UserService доваляют новый метод singleWithAvatar():UserServiceWithAvatarDTO
6. DI:container(UserRepositoryWithAvatarInterface::class, new UserRepositoryWithAvatar)
Ни как не могу понять как все это менять, если есть кто толковый был бы рад списаться и обсудить в каком то чате (whatsapp, discord, ...). Все читаю, читаю, ... и не понимаю как использовать
Дополнительно:
А если потом потребуется добавить еще поле, а спустя время еще одно, и еще?
Будет что-то вроде: UserRepositoryWithAvatarAndCompanyAndSiteAndTelegram ?
Не являюсь экспертом в solid, но не понимаю, почему нельзя расширить новым свойством имеющиеся слои? Кажется, вы пытаетесь только переусложнить.
Зачем вокруг этого марлезонский балет? Ради какой цели?
Соблюдение принципов позволит только не перепахивать по этому поводу половину кода.
Бережно сохранять при этом старые классы, которые никем извне не будут использоваться - оверинжиниринг.
Есть паттерны программирования - вот они про взаимодействие классов, как одни с другими общаются и какие ограничения друг на друга накладывают.
А принципы KISS, SOLID и DRY - они не про архитектуру, они про то, как писать сами классы.
О, например, побуждает не выносить в интерфейс класса детали его реализации, скрывать их за обобщениями, чтобы класс не нужно было всерьез переписывать при обновлениях, но можно было дополнять, сохраняя интерфейс в целом неизменным. Необязательно при наследовании, при правках - тоже.
У вас это все уже соблюдается....
Цей принцип не про недоторканість коду, як ви його розумієте. Наявний файл з кодом можна правити і потрібно, але робити це потрібно так, щоб наявний функціонал не зазнавав змін.
Ответы:
для начала научись грамотно формулировать мысли и приводить работоспособные примеры
1. все строится на интерфейсах которые у тебя нихрена не описаны - откуда-то появляется UserControllerInterface
2. для проброса объектов использовать либо контейнеры, либо фабрики
3. не стоит пытаться создать holy controller подходящий для решения все задач
4. к OCP твой вопрос никак не относится - суть данного принципа в том, что свойства классов приватные, а геттеры/сеттеры - публичные, это позволит расширять класс при этом не модифицируя напрямую родителя
- 4 пункт не понял. Как править если надо добавить новое поле? Или добавлять дополнительный функционал?
- systemaworking,
Как править если надо добавить новое поле?
через публичные/защищенные сеттеры. смысл в том, что только объект может иметь доступ к его свойствам. В приведенном коде ничего подобного нет (программные сущности … должны быть открыты для расширения, но закрыты для модификации)
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос

Второй принцип SOLID - принцип открытости/закрытости (Open/Closed Principle) - гласит, что программные сущности должны быть открыты для расширения, но закрыты для модификации. Это означает, что код должен быть легко расширяемым без необходимости изменения его базовой структуры.
Чтобы соблюдать второй принцип SOLID при изменении кода, следует придерживаться следующих рекомендаций:
1. Используйте наследование и интерфейсы для расширения функциональности классов. Вместо того, чтобы изменять существующий класс, создайте новый класс, который будет наследоваться от базового класса или реализовывать интерфейс.
2. Используйте паттерны проектирования, такие как стратегия, декоратор или адаптер, чтобы добавлять новую функциональность к существующему коду, не изменяя его.
3. Разделяйте код на модули и компоненты, чтобы изолировать изменения и уменьшить зависимости между различными частями программы.
4. Используйте инверсию управления (Inversion of Control) и внедрение зависимостей (Dependency Injection) для разделения создания объектов от их использования. Это позволит легко заменять объекты на более специализированные или расширенные версии.
5. Пишите модульные тесты для проверки функциональности кода перед его изменением. Тесты помогут избежать случайных ошибок и обеспечат стабильность кода при его модификации.
Соблюдение второго принципа SOLID при изменении кода поможет создать гибкую и масштабируемую систему, которая легко адаптируется к новым требованиям без необходимости полного переписывания кода. Правильная архитектура и проектирование помогут сделать код устойчивым к изменениям и обеспечат его долгосрочную поддерживаемость.