Разрушает ли шаблон DataMapper MVC? - PullRequest
8 голосов
/ 19 июня 2009

Я читал о множестве PHP-фреймворков, особенно Zend Framework, но меня смущает вопрос о правильном пути продвижения вперед.

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

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

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

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

Ответы [ 5 ]

2 голосов
/ 23 июня 2009

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

Нечто дополнительное, не связанное напрямую с ответом, но более сфокусированное на DDD:

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

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

2 голосов
/ 21 июня 2009

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

1 голос
/ 10 ноября 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 даже не нужно выставлять себя!

1 голос
/ 22 июня 2009

Из моего прочтения поста вопрос скорее философский, нежели практический.

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

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

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

0 голосов
/ 10 июля 2009

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

  1. Вы можете выбрать, какие свойства обнародовать, так что вам не обязательно раскрывать все внутренности модели
  2. Если вы используете IDE с автозаполнением, все доступные свойства будут открыты после того, как вы начнете вводить «get» или «set» - для меня этого достаточно.
...