Задать вопрос

MVC, как лучше избежать дублирование кода?

Всем привет, я уже 2 года программирую на yii, но, до сих пор не знаю как правильно избегать дублирования кода в моих контроллерах. Все время один и тот же однотипный вопрос во всех моих проектах. Может хабрасообщество сможет мне помочь разобраться ?

Пример

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

Если конкретизировать задачу, то получим:

  1. Пользователь заходит на главную страницу каталога и видит список стран. Он может просмотреть инф-ю/статистику по стране или перейти на страницу выбора области для выбранной страны (CountryController, Country).


  2. Страница выбора области работает по похожему принципу, только с проверкой на существование выбраной статьи (RegionController, Region).


  3. Далее по тому же принципу что описан выше можно попасть на страницу выбора города, с учетом проверки на существование обрасти (CityController, City).


  4. Аналогично попадаем на страницу товара, принцип тот же что и для города (ProductController,Product).


  5. У товара мы можем посмотреть рецензии, принцип все тот же (ReviewController, Review).






То есть очевидно что все 5 контроллеров типа CRUD:

<font color="black"><font color="#0000ff">class</font> CRUDController {<br/>
  <font color="#008000">// тут получаем список всех моделей и передаем вьюхе</font><br/>
  <font color="#0000ff">public</font> function actionIndex(){}<br/>
  <font color="#008000">// страница просмотра инф-ии о модели</font><br/>
  <font color="#0000ff">public</font> function actionView(){}<br/>
  <font color="#008000">// тут обрабатываем создание модели</font><br/>
  <font color="#0000ff">public</font> function actionCreate(){}<br/>
  <font color="#008000">// тут редактирование</font><br/>
  <font color="#0000ff">public</font> function actionUpdate(){}<br/>
  <font color="#008000">// и удаление</font><br/>
  <font color="#0000ff">public</font> function actionDelete(){}<br/>
  <font color="#008000">// к этому методу обращаются view, update и delete</font><br/>
  <font color="#0000ff">protected</font> function loadModel($id){<br/>
     $model=CActiveRecord($<font color="#0000ff">this</font>-&gt;modelClass)-&gt;findByPk($id);<br/>
     <font color="#0000ff">if</font>(!isset($model))<br/>
         <font color="#0000ff">throw</font> <font color="#0000ff">new</font> CHttpException(404,<font color="#A31515">'страница не найдена'</font>);<br/>
  }<br/>
}<br/>
</font><br/>
<font color="gray">* This source code was highlighted with <a href="http://virtser.net/blog/post/source-code-highlighter.aspx"><font color="gray">Source Code Highlighter</font></a>.</font>


Однако контроллерам областей, городов, товаров и рецензий еще нужно проверять верхний уровень, с которого посетитель (или злоумышленник) попал на страницу, например, области могут быть только у существующей страны(то есть RegionCountroller у через $_GET передается idCountry) и т.д.

Очевидно что для всех 4-х контроллеров еще нужны доп. методы для проверки правильности верхнего уровня:

  1. RegionController — loadCountry
  2. CityController — loadRegion
  3. ProductController — loadCity
  4. ReviewController — loadReview




Итого получается 4 дублированных метода. Как избежать такого дублирования? Ниже варианты которые решения которые я вижу. Может посоветуете способ лучше или какой правильней?

  1. Не проверять модель верхнего уровня на существование — по моему, это признак непрофессионализма


  2. Вынести все 5 методов типа loadModel в базовый контроллер: CountryRegionCityProductReviewBaseController — все хорошо, но, логически метод loadCountry больше относится к CountryController у, и не вижу смысла тащить его для CityController и прочих (можно использовать и механизм примесей или поведения, как это называют в yii).


  3. Вынести все 5 методов в статический класс-хелпер.
  4. Сделать loadCountry статическим у CountryController, но, пару людей уже подсказали мне что это плохо, почему — я так и не понял.


P.S.: Код написан под yii, но должен быть понятен и тем кто использует другие фреймворки.

P.S.2: Это моя первая запись на хабре, попробовал учесть все правила написания статей, если что не так — буду рад выслушать.

P.S.3: Хабр срезал вступление, переписал его.
  • Вопрос задан
  • 3675 просмотров
Подписаться 7 Оценить 3 комментария
Ответ пользователя Necro К ответам на вопрос (6)
Necro
@Necro
Правила все ты не учёл — не в том разделе создал.: ) Перекинь в посты.
Ответ написан
Комментировать