2015-12-13 4 views
3

Я пытаюсь понять шаблон MVC в Phalcon.Почему отдельные модели и контроллеры в MVC?

В моем текущем приложении мне нужен только файл ONE для каждого стола. Шаблон содержит datagrid, инструкцию SQL для SELECT, форму, кнопки добавления/редактирования/удаления, окно поиска и все необходимые для взаимодействия с базой данных, такие как информация о подключении (конечно, использование включает как можно больше предотвратить дублирование кода). (Я написал свою собственную сложную структуру, которая преобразует xml-шаблоны в полную HTML-страницу, включая все созданные Javascript-код и CSS, без какого-либо PHP, необходимого для бизнес-логики. Вместо того, чтобы иметь определенные классы PHP для каждой таблицы в базе данных , Я использую только стандартные сценарии операций и классы базы данных, которые могут делать все). Тем не менее, я стараюсь подчиняться веб-стандартам, поэтому изучаю альтернативы.

Я попробовал пример Приора Фалкона и заметил, что страницам компаний требуется модель компаний, CompanyController, CompanyForm и 4 разных мнения. Для меня, по сравнению с моим единственным файловым шаблоном сейчас, наличие большого количества разных файлов слишком сбивает с толку.

Я согласен с тем, что разделение презентации от бизнес-логики имеет смысл, но я не могу понять, почему модель и контроллер должны быть в отдельных классах. Кажется, это только усложняет ситуацию. И, похоже, многие люди уже не могут решить, что должно быть в модели, и что должно быть в контроллере в любом случае. Например, проверка иногда помещается в модель, если она требует бизнес-логики, но в остальном в контроллере, что кажется довольно сложным.

Я работаю только в небольшой команде, поэтому «разделение проблем» (помимо презентации и бизнес-логики) на самом деле не самое главное для нас.

  • Если я решу не использовать отдельные модели и контроллера классов, какие проблемы могут ожидать?
+0

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

+0

Контроллер является посредником между вашими моделями и клиентом. Вы разделяете контроллеры с уровня модели, потому что могут быть разные способы запросить одни и те же модели: например, HTTP API, CLI, Some-other-crazy-api. Во всех этих трех случаях вы взаимодействуете с одними и теми же моделями, но с помощью разных API. Что означает - чем меньше знаний API о вашей модели, тем лучше. – zerkms

ответ

5

Класс Phalcon\Mvc\Model Phalcon предназначен для обеспечения объектно-ориентированного способа взаимодействия с базой данных. Например, если ваша таблица Shopping_Cart, то вы можете назвать свой класс ShoppingCart. Если в вашей таблице есть столбец «id», вы должны определить свойство в своем классе public $id;.

Phalcon также предоставляет вам методы, подобные initialize() и beforeValidationOnCreate(). Я соглашусь, что эти методы могут быть очень запутанными в отношении того, как они работают, и когда они бегают, и почему вы когда-либо хотели бы назвать это в первую очередь.

initialize() вполне понятен и вызывается при каждом запуске вашего класса. Здесь вы можете делать такие вещи, как setSource, если ваша таблица названа иначе, чем ваш класс, или методы вызова, такие как belongsTo и hasMany, чтобы определить ее связь с другими таблицами.

Взаимодействие полезно, так как позволяет легко сделать что-то вроде поиска продукта в корзине пользователя, а затем используя идентификатор, вы получите ссылку на таблицу Accounts и, наконец, возьмите имя пользователя продавца в корзине покупателя.

Я имею в виду, конечно, вы могли бы делать отдельные запросы для такого рода материалов, но если вы определяете отношения между таблицами в самом начале, почему бы и нет?

С точки зрения определения выделенной модели для каждой таблицы в базе данных вы можете определить свои собственные методы управления моделью. Например, вы можете определить метод public function updateItemsInCart($productId,$quantity) в своем классе ShoppingCart. Тогда идея заключается в том, когда вам нужно взаимодействовать с ShoppingCart, вы просто вызываете этот метод и позволяете модели беспокоиться о бизнес-логике. Это вместо написания сложного запроса update, который также будет работать.

Да, вы можете положить этот материал в свой контроллер. Но есть также принцип СУХОЙ (не повторяй сам). Целью MVC является разделение проблем. Итак, зачем следовать MVC в первую очередь, если вы не хотите раздел посвященных моделей? Ну, возможно, вам это не нужно. Не для каждого приложения требуется модель. Например, этот код не использует: https://github.com/phalcon/blog

Лично, после использования структуры модели Phalcon некоторое время я начал нелюбоваться их одноуровневым подходом к Модели. Я предпочитаю многоуровневые модели больше в отношении объектов, сервисов и репозиториев. Вы можете найти такой код здесь: https://github.com/phalcon/mvc/tree/master/multiple-service-layer-model/apps/models Но такое может стать чрезмерным, очень быстро и трудно справиться из-за чрезмерной абстракции. Решение где-то между ними обычно возможно.

Но, честно говоря, нет ничего плохого в использовании встроенного адаптера базы данных Phalcon для ваших запросов. Если вы столкнулись с очень сложным запросом, никто не сказал, что каждая из ваших моделей должна расширить Phalcon\Mvc\Model. Это по-прежнему совершенно здравая логика, чтобы написать что-то вроде:

$pdo = \Phalcon\DI::getDefault()->getDb()->prepare($sql); 
foreach($params as $key => &$val) 
{ 
    $pdo->bindParam($key,$val); 
} 
$pdo->setFetchMode(PDO::FETCH_OBJ); 
$pdo->execute(); 
$results=$pdo->fetchAll(); 

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

Допустим, что полуфункциональные примеры и (построенные только для демонстрационных целей) не так хороши для восприятия хороших моделей проектирования. Я бы посоветовал найти часть программного обеспечения, которое действительно используется в серьезной манере, например код для форумов: https://github.com/phalcon/forum/tree/master/app/models

Phalcon по-прежнему довольно новшеств в структуре, чтобы найти хорошие модели для подражания.


Как вы упомянули, в отношении наличия всех моделей в одном файле это прекрасно. Обратите внимание, как упоминалось ранее, используя setSource в пределах initialize, вы можете назвать свои классы иначе, чем таблица, над которой они работают. Вы также можете использовать пространства имен и сопоставлять классы с именами таблиц. Вы можете сделать это еще дальше и создать один класс для динамического создания всех ваших таблиц с помощью setSource. Предполагается, что вы хотите использовать адаптер базы данных Phalcon. Нет ничего плохого в написании собственного кода поверх PDO или другого адаптера базы данных.

Как вы говорите, разделение проблем не так важно для вас в небольшой команде, поэтому вы можете уйти без каталога моделей. Если это какая-то помощь, вы можете использовать что-то вроде того, что я написал для вашего адаптера базы данных: http://pastie.org/10631358
, тогда вы бросили это в свой каталог приложений/библиотек.Загрузите компонент в вашей конфигурации, как так:

$di->set('easySQL', function(){ 
    return new EasySQL(); 
}); 

Затем в Basemodel вы бы поставил:

public function easyQuery($sql,$params=array()) 
{ 
    return $this->di->getEasySQL()->prepare($sql,$params)->execute()->fetchAll(); 
} 

Наконец, от модели, вы можете сделать что-то просто:

$this->easyQuery($sqlString,array(':id'=>$id)); 

Или определить функцию в глобальном масштабе, так что ваши контроллеры могут также использовать его и т.д.


Есть и другие способы сделать это. Надеюсь, мой компонент «EasySQL» приблизит вас к вашей цели. В зависимости от ваших потребностей, может быть, мой компонент «EasySQL» просто длинный путь написания:

$query = new \Phalcon\Mvc\Model\Query($sql, $di); 
$matches=$query->execute($params); 

Если нет, то, возможно, вы ищете что-то более в направлении

$matches=MyModel::query()->where(...)->orderBy(...)->limit(...)->execute(); 

Который является прекрасно.

0

Модель, вид и контроллер были разработаны для разделения каждого процесса.

Не только Phalcon использует такой подход, но почти сегодня PHP Frameworks использует этот подход.

Модель должна быть местом, где вы сохраняете или обновляете вещи, не следует полагаться на другие компоненты, кроме самой таблицы базы данных (ТОЛЬКО!), И вы просто передаете некоторые логические значения (если выполняется CRUD) или запрос записи базы данных.

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

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

У нас укоротить слово MVC, но на самом деле, мы обрабатываем эти:

HTTP Request -> Услуги Loaded (в том числе обработчиков ошибок) -> Маршрутизатор -> (Route Parser) -> (Отправка на указанный контроллер) -> Контроллер -> (ответьте с помощью JSON или адаптера шаблона | Вызов модели | Вызов ACL | Вызов события | Очередь | Запрос API и т. Д.) -> конец.

Смежные вопросы