Использование классов ORM непосредственно из контроллера в MVC, плохая практика? - PullRequest
7 голосов
/ 02 февраля 2011

Я недавно углубился в использование ORM в своем приложении CodeIgniter, и я выбрал Propel.Теперь это дает мне возможность использовать классы Propels в качестве «модели», но разве это плохо?

Итак, мой код контроллера будет выглядеть следующим образом:

<?php
    class Page extends Controller {
        function __construct() {
            parent::__construct();  
        }   

        function index() {
            $foo = FooQuery::create()->limit(10)->find();
            $data['content'] = array('foo'=>$foo);
            $this->load->view('home', $foo);    
        }
    }
?>

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

Заранее спасибо

Ответы [ 4 ]

7 голосов
/ 02 февраля 2011

Да, это плохая практика.

Модель должна содержать всю логику ваших данных и абстрагировать ее от остальной части программы.Для остальной части приложения модели должны выглядеть как черные ящики, из которых оно получает свои данные.Если вы используете ORM в качестве модели, вы пропускаете абстракцию и тесно связываете свой контроллер с уровнем данных.

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

4 голосов
/ 03 февраля 2011

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

Но помните, что классы Query созданы, чтобы чувствовать себя реальным объектом, и что они скрывают реляционную часть настолько, насколько могут. Вы можете использовать это в ваших интересах. Прочтите эту статью о переписывании ваших SQL-запросов с помощью Query методов , особенно третьего ответа: все больше и больше переходите в свой класс Query, чтобы ваш контроллер не чувствовал, что использует базу данных.

// Instead of this code in your controller,
// tightly coupled to your database logic
$books = BookQuery::create()
   ->filterByTitle('%war%')
   ->filterByPrice(array('max' => 10)
   ->filterByPublishedAt(array('max' => time()))
   ->leftJoin('Book.Author')
     ->where('Author.Name > ?', $fameTreshold);

// You would use this code in your controller
// and create small methods with the business logic in the BookQuery class
$books = BookQuery::create()
  ->titleContainsWord('war')
  ->cheap()
  ->published()
  ->writtenByFamousAuthors();
0 голосов
/ 09 февраля 2012

Многое зависит от того, что вы делаете и почему. в этом примере вы помещаете в запрос предложение limit - это логика бизнеса или отображения? С моей точки зрения, трудно утверждать, что это бизнес-логика - то, что я возвращаю 10 элементов, не имеет отношения к модели - это только то, сколько я думаю имеет смысл использовать на одной странице. Если вы хотите, чтобы это правило было согласованным на всех контроллерах, вы можете установить некоторое значение конфигурации для обеспечения согласованности. Но включение его в модель просто делает модель бесполезной (есть разница между толстыми и тучными моделями)

Я бы сказал, что ограничения, заказы и смещения часто не являются бизнес-логикой. Даже простое, где может или не может быть в зависимости от случая. Если там есть соединение, это признак того, что что-то не так.

Пример от Яна Фабри в основном довольно хороший. filterByTitle для меня выглядит примерно так же, как titleContainsWord. filterByPublishedAt (array ('max' => time ())) намного хуже, чем -> ключ (). В целом, чем меньше контролерам нужно знать о внутренней структуре данных, тем лучше.

0 голосов
/ 02 февраля 2011

Я обнаружил, что это случайное необходимое зло, когда ваш ORM следует шаблону Active Row .

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

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

...