Как правильно реализовывать модели в MVC структуре сайта?

Я делаю свой первый учебный проект используя шаблон MVC.
Модели я начал создавать руководствуясь правилом - для каждой сущности в БД - своя модель.

Сейчас словил ступор вот в таком моменте: Например, у меня на сайте есть блок вывода сообщения, в котором задействованы три сущности: Само сообщение(основная сущность), Пользователь оставивший сообщение, и Файлы прикрепленные к сообщению. Получается, что для того что бы отобразить одно сообщение - мне нужно объединить данные трёх моделей.

Может быть это неправильный подход, и нужно было просто сделать модель сообщения как сущность сайта(то есть уже хранящая в себе данные трех таблиц)? Или совместить два этих подхода, и отдельно создать модели каждой сущности в бд, + модель сущности сайта?
  • Вопрос задан
  • 280 просмотров
Пригласить эксперта
Ответы на вопрос 2
@thyratr0n
Существует множество подходов к решению этой проблемы. Все зависит от того, сколько времени вы готовы потратить на их реализацию, а так же от используемых фреймворков. Если вы говорите про "модель", значит, вы используете паттерны либо ActiveRecord, либо Table.

1. Если вы используете готовые фреймворки, то юзайте инструментарий "из коробки" - для учебного проекта этого будет достаточно.
2. Если вы сами пишете, то тут возможны варианты:
2.1 Можно создавать классы-компоненты (storage), которые будет организовывать выборку и нужным образом компоновать классы между собой:
2.2 Можно создать в БД вьюхи (view), которые объединят нужные данные, а в коде использовать, как единую сущность.
2.3 Можно написать постобработку для CRUD-операций (триггеры в БД, events в коде и тд), которая будет собирать все данные в четвертую таблицу, отдельную. Тогда просто один класс доступа будет.

Варианты во 2-м пункте расположены по возрастанию уровня сложности.

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

class Comment
{
    /**
     * Я бы еще рекомендовал передавать связанные сущности в конструктор, ибо без них комментарий не имеет смысла
     * @param User
     * @param File | null
     **/
    public function __construct(User $user, File $file = null); //я б
  
    /**
     * тут никаких интерфейсов, ибо интерфейсы, дублирующие сущность - моветон
     * @return User
     **/
    public function getUser(): User 
    
    /**
     * @return File
     **/
    public function getFile(): File
}

Либо использовать фабрики. Но фабрики - это уже "на вкус и цвет", как говорится.
Ответ написан
Комментировать
php10
@php10
Разработчик на PHP
У вас должно быть три сущности:
interface MessageInterface
{
    public function setUser(UserInterface $user);

    public function attachFile(FileInterface $file);
}


interface UserInterface
{
.....
}


interface FileInterface
{
.....
}


И должна быть фабрика, которая умеет все это дело собрать вместе, используя MessageInterface::setUser и attachFile. В любом случае модели должны быть отдельно, а данные должны загружаться через сеттеры.

Можно сделать три фабрики и сделать немного по другому:

interface FileFactory
{
    public function getFiles(MessageInterface $message)
}


Хотя такой вариант я не очень люблю. Вариант с сеттерами намного лучше.
Ответ написан
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы