Чем руководствоваться при проектировании классов и их взаимодействия?

Добрый день. Подскажите, пожалуйста, литературу или дайте дельных советов о проектировании сущностей (классов) и их взаимодействия в приложении?

Мои контроллеры содержат всю бизнес логику. И что самое плохое - когда я пытаюсь разбить эту кучу кода в отдельные методы отдельных классов, дабы соблюсти как минимум принцип единой ответственности, я просто напросто теряюсь. В силу малого опыта я не могу понять где заканчивается зона ответственности одной сущности и начинается другой, я не могу понять сколько вообще сущностей фигурирует у меня в коде, т.к. я могу теоретически разбивать их до посинения, что аж на каждый чих будет отдельный класс и в нём 1 метод... Как создавать сервисные классы?...

...а что самое интересное, как с ними потом работать? Внедрять их в качестве зависимостей через, допустим, конструктор в контроллер, а в экшенах уже использовать их API, или внедрять основной сервис, в котором в свою очередь будут внедрены более мелкие сервисы для узких задач, а всё что будет в контроллере (псевдокод, не конкретный фреймворк):

$data = $request->getPost();
$result = $this->mainService->run($data);
$this->view('template', $result);

Так получается? Я, если честно, в смятении. Мне посоветовали почитать про паттерны проектировани, но на мой взгляд паттерны - это элегантное (не всегда) решение конкретных кейсов, а задачи бывают не тривиальные. Какие вопросы нужно задавать себе при проектировании? При определении зон ответственностей сущностей? В конце концов при принятии решений о том, какие вообще будут классы-сервисы, что они будут принимать? Например:

$user->buy($product);
или
$seller->toSell($user, $product);
или...
или...
или...

Очень надеюсь на советы опытных разработчиков. Спасибо!
  • Вопрос задан
  • 1242 просмотра
Пригласить эксперта
Ответы на вопрос 9
Maksclub
@Maksclub
maksfedorov.ru
Чем руководствоваться при проектировании классов и их взаимодействия?

Руководствоваться:
  • Правильными и чистыми абстракциями, которые отражают правильные слои системы, а также позволяют ее расширять и обслуживать. Но следите за проблемой переабстрагирования.
  • Правильной семантикой
  • Понятным и тестируемым кодом
  • Приоритетами, понятливостью для других и ценой разработки
Ответ написан
@dimoff66
Кратко о себе: Я есть
Мне кажется это такие вопросы, которые не могут быть описаны и стандартизированы. Стандартизирован может быть подход. В стандарте может быть указано, что чтобы кататься на велосипеде, вам надо сесть на него и нащупать ногами педали. Если вы ногой не попадете в педали - никакое чтение литературы не поможет, нужно просто садиться, ошибаться, набивать шишки и на этом учиться. Лучшие программисты - те, кто сначала набьет себе шишки, а потом уже читает документацию. Потому что они уже понимают о чем речь.
Ответ написан
MetaAbstract
@MetaAbstract
Разработка интерактивных функциональных прототипов
Это называется паралич анализа) Обопритесь на интерфейс и модель данных, отсюда вылезут модели,роутинг, вьюхи и контроллеры. Запилите что то минимальное, потестите, внесите изменения и обдумайте то, что сделали, тогда увидете, что сделали правильно или нет и это будет опыт, который дальше даст возможность ошибаться меньше. Для ускорения можно какой нибудь бандл простенький взять опенсорсный с большой группой разработчиков и его поизучать. Будет полезно.
Ответ написан
BacCM
@BacCM
C++ почти с рождения
Один из важных и простых критериев при оценке всё ли правильно делаешь: нужно ли из кода одного класса знать что происходит в коде другого. А тем более необходимость вмешиваться в потроха одного класса из другого.
Ответ написан
xmoonlight
@xmoonlight
https://sitecoder.blogspot.com
Если одной строкой: нужно руководствоваться потоками данных.
Если сложнее - нужно определять следующий ряд сущностей:
1. Кто передаёт.
2. Что передаётся.
3. Кому передаёт.

Вот сразу на вашем примере:
/*request принимает POST*/
$data = $request->getPost();

/*mainService формирует $result на основе POST-данных: $data*/
$result = $this->mainService->run($data); 

/*view формирует данные для отображения на основе $result*/
$this->view('template', $result);

Сущности: $request, mainService, view
Данные обмена: POST, $data,$result

Теперь, более короткая запись вашего псевдокода:
{USER/BOT}->[POST]->$request->[$data]->mainService->[$result]->view->{USER/BOT}
Ответ написан
Adamos
@Adamos
Паттерны - не конкретные решения. Это примеры того, как классы могут работать вместе, не зная лишнего друг о друге и о системе в целом. Именно этого обычно и нужно добиваться - чтобы класс работал только с тем, с чем он должен работать, без всякой информации о прочей работе. Имея только аргументы своего конструктора и вызываемых функций. Как это обычно делается в РНР - см. "PHP the right way" и фреймворки.
Ответ написан
DanielDemidko
@DanielDemidko
Программист
Для начала принципом KISS.
Потом SOLID...
Ответ написан
@fpinger
ООП - это искусство усложнять при сохранении простоты.
В любом случае нужно помнить что есть объекты.
Они откуда-то берутся, извлекаются и где-то "существуют" пока они не нужны, а значит об этом нужно позаботиться.
Они разные и могут состоять из других объектов.
Они могут только то, для чего их создали.
Два разных объекта могут быть разными, но являться состояниями абстракции, например до и после.
Исходя из выше сказанного есть сцена, на которой разыгрывается драма объектов и закулисье.
Если смешать сцену и закулисье, то будет всё очень плохо.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через TM ID
Похожие вопросы