Как выбрать представление на основе типа объекта?

#php #oop #model-view-controller

#php #ооп #модель-представление-контроллер

Вопрос:

У меня есть 4 объекта (Роман, короткий рассказ, научно-популярная литература), все из которых происходят из базового класса Book. Пользователь может просматривать страницу сведений о книге, на которой должен отображаться другой набор сведений в зависимости от типа книги. Итак, в идеале, у меня могло бы быть 4 разных сценария просмотра, которые вызывались бы в соответствии с типом выбранной книги. Как бы мне это сделать? Должен ли я хранить ссылку на сценарий просмотра внутри каждого объекта? Должен ли у меня быть оператор switch в действии контроллера для определения правильного представления?

Комментарии:

1. Учитывая, что я понимаю ваш случай, я думаю, я бы порекомендовал выбрать switch.

2. Rails и подобные фреймворки реализуют это не с помощью статического сопоставления имя класса -> некоторый файл, а с помощью соглашения, которое обычно включает плюрализацию и базовый маршрутизатор. Например, маршрут /novel/:novel_id сопоставляется обоим novel.tpl.php просмотр и NovelController.php и Novel.php файлы модели.

Ответ №1:

дайте скриптам / файлам представлений имена в качестве ваших объектов с суффиксом details (например novel_details.php ).

Итак, когда вы отображаете / визуализируете представление, вы анализируете имя объекта с исправлением details

 $this->render( $object->name."_details.php");*
  

Редактировать: * Все зависит от того, какой фреймворк MVC вы используете.

Ответ №2:

Вы внедряете MVC самостоятельно или используете уже существующий фреймворк? Фреймворки типа Rails обычно имеют хорошее сопоставление между классами / методами и запросами, например:

GET /book/view/id/1 --> Book::view(1)

В зависимости от структуры ваших моделей это может отображаться на идентификатор GUID книги; в качестве альтернативы, если вы настаиваете на такой иерархии типов, вы можете предпочесть что-то вроде:

GET /book/view/type/novel/id/3 --> Novel::view(3)

Где id относится к роману, а не к книге, id. Также:

GET /novel/view/id/3 --> Novel::view(3)

будет работать идентично.

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

Ответ №3:

Вы могли бы иметь…

 $bookTypeToView = array(
   'novel' => 'novel.php',
   'short_story' => 'short.php'
   ...
);
  

А затем сделайте что-то похожее на…

 $this->view = isset($bookTypeToView[$book['type']]) ? $bookTypeToView[$book['type']] : 'default';