Изучаю основы ООП и MVC на тестовом проекте - каталог организаций.
Есть несколько вопросов по архитектуре, подскажите, пожалуйста.
Есть организации с названием, описанием.
— Каждая организация входит одну или несколько категорий
— Каждая организация содержит один или несколько адресов.
— — Каждый адрес содержит: адрес, режим работы, контакты (телефон, емейл, и т.д).
Сейчас все, что связано с организациями находится в одном классе Companies.
Есть контроллер, модель и view.
Контроллер и модель имеют методы как на получение списка всех компаний, так и просмотр и редактирование конкретной компании.
Подозреваю, что это неправильно и нужно создавать отдельные классы и подключать их из модели и контроллера:
Компания
— Категория
— Адрес
— — Время работы
— — Контакты
Правильно?
И еще:
Как быть с отображением списка компаний, в каком классе реализовать получение списка и с какого класса получить, например, список категорий, в которые сходит каждая компания из списка?
В чем собственно проблема? Нарисуйте диаграмму классов, отношения между ними. В данном случае можно выделить одну сущность Компания. Компания имеет значения Контактные данные (время работы и адрес входят сюда). Две таблицы в отношении один ко многим, т.е. одна Компания может иметь много Контактных данных.
Хорошей практикой служит написание прослойки или промежуточной модели между контроллером и моделью, которая и содержит в себе всю бизнес-логику
Её ещё называют сервисом
То есть контроллер управляет сервисом, который в свою очередь и дёргает модели
@tmgrom
+ лучше сущности отделить, это может помочь настраивать все сущности в будущем через ORM
разжую -- сейчас у вас скорее всего голые запросы прямо в классе Companies, вы постоянно этот класс меняет, все изменения структуры БД также меняете в этом классе
Далее если бы вы отделили сущности, то можно примерно одинаковую работу вынести в др абстракцию (получение всех элементов, получение одного, получение по фильтру параметров), этим сейчас в современной разработк занимаются ORM,
то есть по сути вам в сущности нужно будет только указать таблицу, к которой сущность привязана, указать связь на др сущности и перечень полей сущности с их типами для валидации... так примерно в Eloquent ORM (от Ларавел)
Как понимаете дальнейшее обслуживание можно сильно облегчить этим (так и сделано в фреймворках)
Подходов масса, и все имеют свои недостатки и преимущества. Я обычно разбиваю на вменяемые "физические" сущности: адрес, телефон, компания, почта... в таком случае объединения в коллекции принадлежностей могут быстро сменять метод отношений от один ко многим к многие ко многим простым добавлением таблицы связей. В логике тоже будет всего 2-3 мелкие правки. Хранить все в одной таблице/сущности наиболее худший вариант.
Идея MVC, MVP, MVVM и тд в том , что бы отделить бизнес модель от ui. Т.е. безнес модель не должно волновать какой там будет контролер и проч.
поэтому рассуждая о модели и оглядываясь на контролера сигнал, что что-то не в порядке в нашей архитектуре.
Далее, для уменьшения запутанности в будущем ))) лучше бизнеслогику описывать в сущностях предметной области. Например
Компания
Категория
Адрес
и проч
Реализация должны быть скрыты.
Итого выбор из двух представленных моделей сводится к тому какая модель ближе к предметной области:
Категория.выдатьСписокОрганизаций
Организация.выдатьСписокАдресов
или
Компания.выдатьСписокКатегорий
Компания.выдатьСписокАдресов
По сути отличие только в первой строке. И отличие в том что чаще используется : зависимость категорий от организаций или наоборот. Что чаще, то должно реализовываться проще. в случае если нужны две зависимости, в модели должны быть реализованы два случая.
Замечу, что реализация хранения объектов бизнеслогики должно быть скрыто за интерфейсом типа репозитория. Он будет выдавать готовые сущности независимо от базы данных или получения данных.
Вот типа так. Хотя срезать углы никто не запрещает уменьшая количество слоем в архитектуре или интерфейсов. ))) Просто нужно понимать, что делая так мы повышаем количество связей между частями системы, но уменьшаем количество написанного кода. Баланс зависит от случая.