MVC и состояние программы - должны ли модели быть глупыми? - PullRequest
1 голос
/ 28 января 2011

Я использую фреймворк, который использует парадигму MVC. Это CodeIgniter, но мой вопрос не о фреймворке, а о лучших практиках работы с MVC.

Я использую переменные $ _SESSION для поддержки некоторых переменных состояния (выбор пользователя, некоторые временные настройки, некоторые параметры фильтрации данных). Это достаточно легко сделать, но я обнаружил, что я разделяю использование этих переменных на модели и контроллеры. Иногда я обновлял один в контроллере и смотрел его в модели. Это начало «пахнуть» забавно, потому что мне пришло в голову, что было бы не очень хорошей идеей, чтобы модели «знали» обо всех этих настройках. Разве модели не должны просто принимать запросы на выборку / манипулирование данными и интересоваться только тем, что было явно в запросе (без необходимости поиска внешних переменных)?

Вот пример: У меня есть одна переменная сеанса с именем $ _SESSION ['regionFilter']. Он создается и обновляется в контроллере и представляет собой регион продаж, в который пользователь хочет «углубиться». Когда контроллер запрашивает некоторые данные из модели, я в настоящее время заставляю модель искать переменную $ _SESSION ['regionFilter'] и использовать ее при создании своего SQL для базы данных. Кажется, что было бы более разумно сделать модель «глупой» в отношении состояния программы и заставить контроллер каким-то образом связать переменную $ _SESSION ['regionFilter'] в свой запрос, если он этого хочет.

Есть мысли? Спасибо!


Редактировать: Спасибо за обсуждение, ребята. Я знаю о перекрывающихся вопросах, но мне было трудно найти общее обсуждение по этой теме - мои поиски «состояния программы модели MVC» выявили множество вопросов о дискуссиях, специфичных для ASP.NET-MVC, которые увязли в реализации подробности.

Я пометил вопрос как закрытый. Еще раз спасибо за ваши мысли!

Ответы [ 3 ]

4 голосов
/ 28 января 2011

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

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

Предоставьте метод в модели, который будет фильтровать соответствующим образом, а затем непременно передаст переменную сеанса из контроллера, но модель не имеет представления о том, что фильтр получен из переменной сеанса. Это просто фильтр.

РЕДАКТИРОВАТЬ: Чтобы уточнить, я бы сказал, что состояние сеанса является частью контроллера , определенно не модель .

2 голосов
/ 28 января 2011

В общем, у меня есть доменные модели, которые являются только государственными.Я знаю, что это не сулит ничего хорошего некоторым пуристам из теории Эвана, но оно хорошо работает для создания моделей, которые являются переносимыми даже в гетерогенных системах.Другими словами, это хорошо работает для SOA (хотя мы можем утверждать, что шаблон суррогата лучше на последующем этапе?)Модель предметной области, несмотря на то, что многие образцы объединяют два понятия.Ваша модель - это модель, объединенная с представлением (ViewModel в шаблоне MVVM).Если у вас есть это логическое разделение, ваша модель представления может быть комбинацией исходной «модели» (модели предметной области?) И любой другой информации, которую вам нужно отобразить.Это делает чистое разделение проблем также, что приятно.

1 голос
/ 28 января 2011

Если в вашем классе поиска требуется ваш фильтр региона, используйте Inpendency Injection, чтобы передать его в него.Ваш фильтр региона должен быть классом модели домена.Этот фильтр региона должен не знать, где вы храните свои данные между запросами.Просто убедитесь, что у Region Filter есть он, когда он ему нужен.

Как класс модели домена, он не принадлежит контроллеру, а модели.Обратите внимание, что Модель - это не только база данных, но и все, кроме пользовательского интерфейса.Контроллер является частью уровня пользовательского интерфейса.Его единственная цель - делегировать текущий Запрос соответствующим моделям.

Другими словами, вы должны делать что-то вроде этого:

public function searchAction()
{
    $customerSearch = new CustomerSearch;
    $customerSearch->setFilter(new RegionFilter($_SESSION));
    $results = $customerSearch->fetchResults();

    // do something with $results on User Interface
}

Обратите внимание, что я не согласен с ответомв другом месте на этой странице данные или состояние сеанса принадлежат контроллеру.Это не так.Данные сеанса - это просто сохраненные данные.Как и любые другие постоянные данные, они относятся к постоянному слою (который также является частью модели).Забудьте, что это данные сеанса.Это данные фильтра регионов.

Имеет смысл наложить API на $_SESSION (или любой суперглобальный), чтобы предотвратить связь с конкретной средой.Но класс RegionFilterStorage_Session все равно будет классом модели.

...