Согласование Закона Деметры с моделями

У меня есть объект модели данных User. В моем приложении также есть некоторые другие объекты модели данных, например, Fork и Options. У пользователей есть форки и ответвления. Мое приложение должно выполнять множество запросов с некоторой комбинацией информации о пользователе/форке/параметрах и т. д. Например, вы можете увидеть страницу пользовательских вилок. Для этого потребуется запрос, который присоединяется к этому пользователю (например, к пользователю, вошедшему в сеанс) в Forks.

Я не хочу нарушать Закон Деметры, и я также обычно против геттеров (и сеттеров) в целом, поэтому я не хочу реализовывать User::getID() или User::getUsername().

Однако альтернатива мне не кажется намного лучше. В итоге я реализовал различные методы в User для выполнения этих запросов (например, User::getForks()). В целом это работает, но класс User стал монолитным, что по-своему плохо.

Более того, я не уверен, как разрешить запрос двух объектов модели данных. Например, у меня может быть User с идентификатором и Fork с идентификатором, и я хочу проверить, что вилка принадлежит пользователю. Для этого требуется, чтобы либо Fork раскрывал свой идентификатор пользователю, либо User раскрывал свой идентификатор Fork, либо оба раскрывали свои идентификаторы контроллеру (или чему-то еще). Ни один из них не кажется желательным, и я не уверен, что выбрать. Есть ли какая-то другая альтернатива, которую мне не хватает?

На другом аналогичном этапе я не уверен, как лучше всего добавить информацию в представление. У меня есть объект представления, и обычно я использую такой метод, как User::addForksToView(View $view), который запускает запрос или запросы и выполняет некоторую обработку, но это также увеличивает размер и ответственность User. Я думаю, что это аналогичная проблема.


person Explosion Pills    schedule 05.04.2012    source источник


Ответы (1)


Вместо метода getForks в объекте User используйте ForksFactory или что-то подобное. Фабрика может иметь такие методы, как fromUser(User $user) и byId($id). Таким образом, объект User не имеет скрытой зависимости от объекта Fork. , и, вероятно, скрытая зависимость от доступа к базе данных. ForksFactory зависит от базы данных и содержит код, необходимый только для получения данных и создания Forks, это все, что он умеет делать. Тогда как объект Fork не будет зависеть от базы данных, а теперь объекту User не нужно ничего знать о Fork, на самом деле Fork вообще не может существовать, а User это не волнует. Это идея одноцелевого объекта.

Что касается геттеров и сеттеров, почему бы не сделать общедоступными такие свойства, как id и name? Кроме того, вы можете использовать магические методы __get и __set, чтобы контролировать, какие свойства рассматриваются как доступные только для чтения, если это вас беспокоит. В противном случае вы также можете раскрыть свойства - это вполне приемлемо.

Другой код, который вы упомянули, звучит так, как будто он страдает от той же проблемы — один объект, одна цель. Теоретически каждый объект должен стоять изолированно или иметь какие-либо зависимости, внедренные в конструктор. Ваши объекты не должны требовать, чтобы был определен другой объект, или один из его методов не будет работать.

person Chris Baker    schedule 05.04.2012