2013-06-24 3 views
0

Доброе утро всем. Недавно я прочитал статью о шаблоне mvc, в которой говорится, что большинство инфраструктур php внедрили шаблон mvc неправильно. php master mvc pattern part 1 php master mvc pattern part 2 Ну после прочтения этого и рассмотрения этой реализации возник вопрос. Как бы вы назвали в образе метод, вызванный в модели? То, что я пытаюсь сказать, это. Это часть кода из статьи.Модель - Вид - Контроллер новая перспектива

<?php 
$model = $_GET['model']; 
$view = $_GET['view']; 
$controller = $_GET['controller']; 
$action = $_GET['action']; 

if (!(empty($model) || empty($view) || empty($controller) || empty($action))) { 
    $m = new $model(); 
    $c = new $controller($m, $action); 
    $v = new $view($m); 
    echo $v->output(); 
} 

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

<?php 
class Index extends Controller 
{ 
    public function __construct(IndexModel $model, $action) 
    { 
     $this->model = $model; 
    } 
    public function someAction($id) 
    { 
     $this->model->getData($id); 
    } 
} 
class Index extends View 
{ 
    public function __construct(IndexModel $model, $action) 
    { 
     $this->model = $model; 
    } 
    public function someAction() 
    { 
     $this->model->getData(); 
    } 
} 
class Index extends Model 
{ 
    public function __construct() 
    { 
     //Some Code Here 
    } 
    public function someAction() 
    { 
     // Inserting Data into database. 
    } 
} 

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

+2

Это ужасная «реализация» MVC тоже и далека от правильной, а также – deceze

+0

, какая часть? код из статьи или часть кода с классами? : D – Bogdan

+0

Я согласен, что это плохая реализация; но технически говоря, в MVC нет ничего, мешающего вам получить доступ к модели через представление. Вы можете проверить MVP (Model-View-Presenter), чтобы гарантировать, что ваш рабочий процесс всегда проходит через Presenter (аналогично Controller in MVC). – bmartins

ответ

4
  1. Там нет 1: 1 корреляции между контроллерами и частей модели (примечание: не "модели", но частей _The model_). Просто потому, что у вас есть «контроллер индекса», это не значит, что вам нужна «индексная модель» и «индексный вид».
  2. M, V и C не сконструированы вместе. Контроллер сконструирован, а затем он решает, какой модельный метод загружать/строить/вызывать и какое представление должно отвечать на запрос.
    1. Существует дискуссия о том, должен ли контроллер вызывать представление, или должна ли модель «обновлять» представление. Поскольку веб-запросы являются эфемерными, и нет никакого «постоянного» представления, последнее мало имеет смысла в PHP; это более подходит для оригинального SmallTalk или Obj-C или аналогичных сред.
  3. Первый фрагмент кода имеет ужасное использование empty (см here) и, опять же, не следует строить все части вместе.

MVC следует подходить так:

  • Модель являетсяприложение. Это не просто «обработчик данных» или «хранилище данных», это основное приложение. Все, что делает приложение, логическая логика - это «модель». Это включает отправку уведомлений по электронной почте, работу по обслуживанию базы данных и таких вспомогательных вещей, все они в модели.
  • Вид отвечает за выпуск продукции различных форм. Представление должно иметь возможность взаимодействовать с моделью, чтобы получить данные, необходимые для выполнения своей работы. Данные не следует «вставлять» в представление, представление должно иметь возможность «тянуть» нужные ему данные; в противном случае что-то внешнее по отношению к представлению должно знать, какие данные требуется для представления, а это значит, что логика представления больше не содержится в представлении.
  • Контроллер - это всего лишь маленький клей, который оставлен для вызова правильного метода модели и просмотра в ответ на входящий запрос.

Я обычно структурировать эти части, как это:

  • Модели состоит из различных частей, включая обработчик хранения данных, «примитивы» (классы, модель отдельных бизнес-объекты) и «услуга». «Сервисы» содержат все «действия», которые может выполнять ваше приложение и формировать модельный API. Всякий раз, когда вы хотите «сделать» что-то в приложении, например «зарегистрировать пользователя» или «получить все записи для диапазона дат X-Y», есть один специализированный метод для него в API-интерфейсе службы. Просто взглянув на этот сервисный API, вы сможете перечислить все, что делает ваше приложение.
  • Существует один объект, который является либо «диспетчером», либо «локатором обслуживания», либо просто контейнером инъекции зависимостей, который упрощает создание экземпляров этих классов обслуживания и позволяет кому-то их называть. Контроллер получает один из них, а также вид.
  • Существует маршрутизатор, который выполняет некоторую «грубую маршрутизацию» на основе URL-адреса, вызывая метод контроллера. Контроллер дополнительно просматривает детали запроса и решает вызвать метод модели и/или ответить на представление.
  • Вид может определять наилучший способ представления некоторых данных на основе специфики запроса, например. отвечать ли с HTML-страницей или блоком данных JSON. Yay для сервисов RESTful.

В грубом псевдокода:

$r = new Router; 
$r->route($_GET, $_POST, $_SERVER); // or something like that 

Это рассылает что-то вроде:

class FooController { 

    public function __construct(ServiceLocator $services) { ... } 

    public function bar(Request $request) { 
     $request->assertIsPost(); 
     $this->services->locate('Baz')->froogleTheWibbles($request->getPostParams()); 
     (new BarView($this->services))->displayWibbles($request); 
    } 

} 

class BarView { 

    public function __construct(ServiceLocator $services) { ... } 

    public function displayWibbles(Request $request) { 
     switch ($request->accepts()) { 
      case 'html' : 
       $this->loadTemplate(...); 
       ... 
      case 'json' : 
       echo json_encode($this->services->locate('Baz')->getWibbles()); 
     } 
    } 

} 

И модель делает все, что нужно сделать ...

class Baz { 

    public function froogleTheWibbles(array $data) { 
     foreach ($data as $wibbleData) { 
      $wibble = new Wibble($wibbleData); 
      $this->wibbleStore->save($wibble); 
     } 
     ... 
    } 

} 

Для MVC нет «одного ответа», важная часть состоит в том, что модель содержит все, что ваше приложение «делает» независимо от ввода и вывода, представление может выдавать правильный выход по мере необходимости, насколько это возможно, и контроллер - это всего лишь немного клея, который обрабатывает условия ввода. Существуют различные способы реализации этого. Важным принципом проектирования должно быть понимание того, что представление и контроллер взаимозаменяемы для разных условий (веб-страница, JSON API, XML API, SOAP API, вызов CLI, узел ZeroMQ и т. Д.), Но «модель» - нет.

+0

Я не уверен, что вещи, подобные отправке писем, принадлежат модели и что контроллер - это просто «клей». Представьте, что разные контроллеры, обращающиеся к одной и той же модели, сначала нуждаются в отправленном электронном письме, а второй - нет. Посмотрите на Zend2 в сочетании с Doctrine, например. Внутри модели нет бизнес-логики. – DanFromGermany

+1

Нет бизнес-логики внутри модели ?! Кажется, что целиком не хватает точки MVC. Бизнес-логика - это вся модель! Опять же, контроллер * взаимозаменяем * в зависимости от того, как вы хотите предоставлять услуги своего приложения. У вас есть веб-страница, которая позволяет пользователю что-то делать, но у вас также есть XML API, который позволяет приложениям делать то же самое. Вход * * совсем другой, и его нужно обрабатывать по-разному, но действие такое же. Если вы держите бизнес-логику в контроллере, вам необходимо ее дублировать. Нет, BL входит в модель, контроллер адаптируется в зависимости от формата ввода. – deceze

+0

Веб-страница и XML API, это два разных вида на 1 контроллер и 1 модель .... – DanFromGermany