Нарушает ли шаблон DataMapper MVC?

Я читал о нескольких фреймворках PHP, особенно о Zend Framework, но я не понимаю, как правильно двигаться вперед.

Zend Framework не использует ActiveRecords, а вместо этого использует шаблон Table Data Gateway и Row Data Gateway, а также использует DataMapper для сопоставления содержимого Row Data Gateway с моделью, потому что ActiveRecord ломается, когда ваши модели не имеют 1: 1 сопоставление с таблицами вашей базы данных. пример этого в Руководство по быстрому запуску Zend.

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

Мой вопрос: если вы удалите эти геттеры и сеттеры, как вы будете отображать свои представления? В какой-то момент данные должны попасть в представление, чтобы вы действительно могли что-то показать пользователю. Следование совету DDD, кажется, нарушает разделение между M и V в MVC. Следование примеру MVC и Zend, кажется, ломает DDD и заставляет меня вводить множество геттеров, сеттеров и DataMappers для всех моих моделей. Помимо того, что это много работы, это также, кажется, нарушает DRY.

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


person Sander Marechal    schedule 19.06.2009    source источник


Ответы (5)


Используя объекты-значения, вы можете исключить некоторые из этих общедоступных методов установки. Вот описание различия между объектами Entity и Value Objects. Объекты-значения неизменяемы и часто привязаны к сущности. Если вы передаете все значения с помощью конструктора, вам не нужно устанавливать эти свойства из внешнего кода.

Что-то дополнительное, не связанное напрямую с ответом, но больше ориентированное на DDD:

(Отказ от ответственности: единственное, что я знаю о Zend Framework, это то, что я прочитал в связанной статье.) Zend Framework использует DataMappers вместо репозиториев. Это действительно DDD-иш? Что ж, интерпретация репозитория Фаулером может сказать нет. Однако Эрик Эванс утверждает, что репозиторий DDD может быть очень простым. В простейшем случае репозиторий является DataMapper (см. книгу DDD). Что-то более сложное и все еще DDD смотрите в статье Фаулера. DDD имеет концептуальный репозиторий, который может отличаться от определения шаблона.

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

person Kevin Swiber    schedule 23.06.2009
comment
Спасибо. Эта статья Devlicious хорошо читается. Буду читать и остальные серии. - person Sander Marechal; 24.06.2009
comment
Это хороший ответ, и я бы добавил, что с геттерами, сеттерами не так. На самом деле, их наличие — отличный способ добавить логику проверки. Делать свойства общедоступными — это быстро и грязно, и это нормально при прототипировании, но не является хорошим долгосрочным решением. Предположим, вы хотите изменить имя свойства. Если вы сделаете это, каждый фрагмент кода, который обращается к этому свойству, должен быть изменен. Если вы используете универсальное имя для метода доступа, вам не нужно изменять клиентский код. Кроме того, Doctrine — гораздо более функциональное решение, чем Zend DB. Я бы не рекомендовал Doctrine1, но попробуйте Doctrine2. - person Wil Moore III; 20.08.2010

Вам не нужно реализовывать все геттеры/сеттеры, вы можете использовать __get() и __set(). В чем тогда проблема?

person Tomáš Fejfar    schedule 20.06.2009

Судя по моему чтению поста, вопрос скорее философский, чем практический.

У меня нет времени писать подробно, но вот мои пять копеек. Хотя я согласен с тем, что вы хотите ограничить количество запросов на получение и установку, потому что класс должен скрывать свои внутренние компоненты, вам также необходимо учитывать, что Java и PHP — это разные инструменты и разные цели. В веб-среде ваши классы создаются и удаляются с каждым запросом, поэтому код, который вы пишете, не должен зависеть от огромных классов. В статье, на которую вы указали, автор предлагает разместить логику представления в классе. Это, вероятно, не имеет смысла в Интернете, поскольку я, вероятно, захочу представить представление в нескольких форматах (rss, html и т. д.). Таким образом, использование методов доступа (get & set) является неизбежным злом. Вы все еще хотите использовать их вдумчиво, чтобы не выстрелить себе в ногу. Суть в том, чтобы ваши классы выполняли работу за вас, а не заставляли их выполнять работу извне. Получая доступ к своим свойствам с помощью метода, а не напрямую, вы скрываете внутренности, которые вам нужны.

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

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

person Community    schedule 22.06.2009
comment
Спасибо. Мой вопрос действительно больше философский, чем практический. Включение логики представления в модель предметной области показалось мне проблематичным (поскольку это нарушает MVC), и это вызвало вопрос. Что я действительно надеюсь увидеть, так это несколько практических примеров, которые ясно показывают теорию в действии. Если это действительно баланс между Domain Driven Design и MVC, то мне бы хотелось посмотреть, как другие люди решают очевидный конфликт между ними. - person Sander Marechal; 23.06.2009

Здесь есть два подхода: то, что я называю подходом «скажи, а не спрашивай», и другой подход — подход ViewModel/DTO. По сути, вопросы вращаются вокруг того, что, по вашему мнению, является «моделью». Скажи, не спрашивай, требует, чтобы единственный способ, которым объект может быть экстернализован, исходил от самого объекта. Другими словами, для рендеринга объекта у вас будет метод рендеринга, но этот метод рендеринга должен будет взаимодействовать с интерфейсом. Что-то вроде этого:

class DomainObject {
   ....
   public function render(DomainObjectRenderer $renderer) {
        return $renderer->renderDomainObject(array $thegorydetails);
   }
}

В контексте Zend Framework вы можете создать подкласс Zend_View, и ваш подкласс реализует этот интерфейс.

Я делал это раньше, но это немного громоздко.

Второй вариант — преобразовать вашу доменную модель в объект ViewModel, который похож на упрощенное, сглаженное, «растянутое» представление ваших данных, настроенное для каждого конкретного представления (с одной ViewModel на представление), и на обратном пути. , преобразуйте данные POST в EditModel.

Это очень популярный шаблон в мире ASP.NET MVC, но он также похож на шаблон класса «DTO», используемый для передачи данных между «слоями» в приложении. Вам нужно будет создать картографы, чтобы сделать за вас грязную работу (на самом деле мало чем отличается от DataMapper). В PHP 5.3 вы можете использовать отражение для изменения частных свойств, поэтому вашему DomainObject даже не нужно раскрывать себя!

person blockhead    schedule 09.11.2009

На мой взгляд, реализация геттеров и сеттеров имеет два преимущества:

  1. Вы можете выбрать, какие свойства сделать общедоступными, поэтому вам не обязательно раскрывать все внутренности модели.
  2. Если вы используете IDE с автозаполнением, все доступные свойства будут на расстоянии клавиши TAB, когда вы начнете вводить «получить» или «установить» — одного этого для меня достаточно.
person inxilpro    schedule 09.07.2009