PHP MVC – Как контроллер и просмотр могут обращаться к одному экземпляру модели?

Я разрабатываю свой собственный PHP MVC для приложения базы данных, которое я уже выполнил, но используя монолитные классы, которые делают все: обработка MySQL, обработка ввода и отображение. Он отлично работает, но это кошмар для отладки и внесения изменений! Я недавно обнаружил MVC и в процессе перезаписи приложения – все это на чертежной доске в данный момент, поэтому у меня на самом деле нет кода для обмена с вами.

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

Чтобы объяснить, на что я застрял, я приведу пример:


Пример: отправка формы с данными, что не позволяет проверить модель

Передний контроллер:

  • Загрузите соответствующий контроллер и вызовите действие ProcessForm

контроллер:

  • Создайте экземпляр класса Model и вызовите методы для загрузки и проверки данных

Модель:

  • не удалось выполнить проверку: сгенерируйте список ошибок и верните 'false'

контроллер:

  • Если модель вернула «true», перенаправление на страницу индекса
  • Он вернул «false»: вызовите View

Посмотреть:

  • Создайте экземпляр класса модели и извлеките данные
  • Отображение данных и сообщений об ошибках

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

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

Ну .. кулаки всех, нет «моделей». Модель в шаблонах дизайна MVC и MVC – это слой , который содержит множество структур, так же как слой представления содержит контроллеры, представления и некоторые другие вещи.

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

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

class ServiceFactory { private $cache = array(); public function create( $name ) { if ( array_key_exists($name, $this->cache) === false ) { $this->cache[$name] = new $name; } return $this->cache[$name]; } } 

Это «очень тупой» вариант сервисной фабрики.

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

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

Классы доменов (модели)

Классы домена просто содержат данные, чтобы дать им контекст. Например, у вас может быть класс домена Person .

 class Person { private $name; private $age; ... public function getName() public function getAge() ... } 

Контроллеры

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

 class PersonController { private personService; public function list(Bag bag) { bag.add('personList', personService.listAll()); ... Give bag of data to the correct view ... } } 

Сервисы

Службы обрабатывают логику приложения. В основном взаимодействия между объектами, которые содержат логику домена и абстракции хранилища.

 class PersonService { public function listAll() { ... Do the logic to find all persons ... return $persons; } } 

Просмотры

Представления просто отображают данные, данные им контроллером. У нее нет собственной модели.


Он не решает все проблемы, но, по крайней мере, это достойный старт, чтобы ваша структура была правильной.

Spring Framework (Java) имеет очень хорошую реализацию MVC. См. Вдохновение http://static.springsource.org/spring/docs/3.0.x/reference/mvc.html

без того, чтобы Контроллер передавал свой экземпляр модели непосредственно в представление

Зачем? Это то, что происходит нормально, и это, вероятно, то, что вы также должны делать. Экземпляр модели может хранить ошибки проверки внутри, и если контроллер передает один и тот же экземпляр в представление, проблема в том, как распространять эту информацию, решает сам.