Должен ли я полностью отделить Модели и ORM в MVC? - PullRequest
6 голосов
/ 19 ноября 2011

Я работаю над приложением MVC на PHP, которое не использует никаких фреймворков. Я использую RedBean для своего ORM, который реализует шаблон datamapper и работает очень похоже на доктрину .

Согласно этому вопросу , я понимаю, что модель НЕ является объектом ORM. В моем проекте у меня есть следующие сценарии:

  • «Сложные» модели, которые должны общаться с большим количеством таблиц в базе данных:

    • Одна из этих моделей может быть чем-то вроде системы разрешений RBAC. Контроллер должен иметь возможность вызывать что-то вроде $permission->isAllowed($controller, $action, $resource), чтобы определить, разрешено ли пользователю выполнять запрошенное действие. Кроме того, он может позвонить $permission->getPermissions(), чтобы получить список разрешений, которые есть у пользователя.
  • «Простые» модели, где модель обычно может быть представлена ​​1 таблицей в базе данных:

    • Одной из таких моделей будет модель User. Например $user->changeRank(), $user->addPoints() и т. Д.

Проблема, с которой я сейчас сталкиваюсь, заключается в том, что, просматривая большую часть документации для различных сред, я вижу, что в примерах контроллер напрямую взаимодействует с ORM. Например, вот пример контроллера из symfony2 :

public function createAction()
{
    $product = new Product();
    $product->setName('A Foo Bar');
    $product->setPrice('19.99');
    $product->setDescription('Lorem ipsum dolor');

    $em = $this->getDoctrine()->getEntityManager();
    $em->persist($product);
    $em->flush();

    return new Response('Created product id '.$product->getId());
}

Если ORM НЕ является моделью, почему контроллеру разрешено напрямую взаимодействовать с ним? Разве он не должен взаимодействовать с моделью, которая выглядит следующим образом?

class ProductModel{
   public function newProduct($name, $price, $description){
        $product = new Product();
        $product->setName('A Foo Bar');
        $product->setPrice('19.99');
        $product->setDescription('Lorem ipsum dolor');

        $em = $this->getDoctrine()->getEntityManager();
        $em->persist($product);
        $em->flush();
   }
}

Наконец, я обрисовал в общих чертах модель permissions ранее. Считается ли это моделью в контексте MVC? Этот класс будет использоваться во всем приложении, так как большинству действий необходимо проверять наличие прав доступа.

1 Ответ

2 голосов
/ 19 ноября 2011

ORM (Object Relational Mapper) используется для генерации файлов модели.Файлы моделей используются для связи между приложением и базой данных (моделью).Похоже, вы разбираетесь в процессах ORM, но вы можете быстро перефразировать (используя доктрину в качестве примера) для тех, кто может не быть, и я могу стать счастливчиком и ответить на ваш вопрос.

Вы используетеORM для анализа вашей схемы базы данных, которая генерирует файл схемы.Теперь с помощью этого файла схемы вы можете изменить его в соответствии с потребностями своего приложения.Например, вы можете добавить actAs: { Timestampable ~} или actAs: NestedSet: hasManyRoots: true.Кроме того, вы захотите использовать этот файл схемы для настройки того, как должны вести себя отношения между объектами (например, 1: M, M: M с использованием refClass и т. Д.)

Как только ваш файл схемы готовчтобы пойти, вы даете команду для генерации файлов модели.Файлы моделей - это классы, которые вы можете использовать в своем приложении для получения доступа к базе данных.Таким образом, контроллер на самом деле обменивается данными с моделью (вашей базой данных) через файлы, сгенерированные ORM.

Приведенный вами пример является хорошим, так как вы можете разгрузить большую часть бизнес-логики из ваших действий.(контроллер страницы) и в вашу модель.Таким образом, к той же логике можно получить доступ из других кодов без необходимости иметь дело с какой-либо логикой уровня контроллера.То, что доктрина делает (и делает propel тоже), позволяет вам создавать классы «Table» (или «Peer»).Эти классы действуют как контейнеры для работы с несколькими объектами.Именно в этих классах вы должны добавить свою бизнес-логику, как вы продемонстрировали во втором примере.

Конечная цель - максимально упростить ваши действия, просто обрабатывая параметры запроса и обработку формы, а затем передавая значенияк вашей модели через «Таблица» или пользовательские классы, которые вы разрабатываетеСледуя этой парадигме, вы можете получить многофункциональное приложение с урезанными действиями и централизованной бизнес-логикой.

Редактировать ---

Извините, я пропустил ваш последний вопрос относительно вашего разрешения API.Из того, что вы опубликовали, похоже, что он следует парадигме MVC в том, что у вас есть объект разрешения и вы используете его как API между контроллером и базой данных.

...