Шаблон для построения большой иерархии объектов - PullRequest
8 голосов
/ 25 января 2010

У меня проблема с относительно большой иерархией объектов:

  • игра имеет один менеджер сообщества
  • менеджер сообщества имеет одну сеть
  • сеть имеет много игроков
  • сеть имеет много друзей
  • игрок имеет одного менеджера стратегии
  • игрок имеет одну память
  • игрок имеет один район
  • окрестности имеет много игроков
  • менеджер стратегий имеет множество стратегий

Как видите, иерархия является относительно сложной и, по крайней мере, в одном месте циклической (сеть имеет много агентов, имеющих одну окрестность, которая имеет одну сеть). В настоящее время я использую метод статического конструирования в классе GameFactory для построения всей иерархии, но я уверен, что это наименее гибкий способ сделать это!

С точки зрения построения сложной иерархии объектов, какой шаблон лучше всего использовать? Я прочитал шаблоны Factory Method, Abstract Factory и Builder и думаю, что один из заводских шаблонов подходит, но я не знаю, как применить его к такой сложной иерархии?

На мой взгляд, мне понадобится много фабрик для каждой части системы, но это приведет к коллекции фабричных классов, отражающих классы моделей.


Редактировать: Из приведенных выше предложений стало ясно, что я должен был объяснить больше о том, почему я требую, чтобы фабрики строили свои иерархии объектов, а не позволяли самим конструкторам строить свои зависимости.

Это потому, что я использую внедрение зависимостей, чтобы помочь в разработке через тестирование. Я использую подход к тестированию, основанный на принципах «mockist», который требует способности вставлять макеты, представляющие зависимости объекта, и поэтому я должен избегать использования new в любых конструкторах.

Судя по приведенным выше предложениям, существует несколько возможных способов сделать это:

  • Создайте вторичный конструктор в каждом классе, который строит любые зависимости, требуемые для создаваемого объекта. Это позволяет внедрять зависимости и строить простую иерархию объектов.
  • Имейте фабричный класс (или один или их иерархию в зависимости от типа используемого фабричного образца), сопоставляющийся с каждым классом домена, чтобы иметь дело с его конструкцией.
  • Используйте комбинацию этих методов, когда фабричные классы создаются только тогда, когда есть что-то, что изменяется в процессе конструирования (т. Е. При определенных обстоятельствах необходимо создавать разные подклассы)

Я склонен идти по последнему маршруту. Каков консенсус относительно наилучшего подхода в этой ситуации?


Редактировать: Я отменяю текущий ответ (ответ Патрика Карчера), так как теперь, когда фокус этого вопроса прояснен, ни одно из предложений не является полным ответом.

Ответы [ 3 ]

4 голосов
/ 25 января 2010

Важно понимать , почему именно вам нужен завод. Как и в случае с множеством «хороших» практик, фабрика может принести определенные преимущества, которые вы иногда хотите и которые вы получаете только при правильном их использовании.

Часто фабрика - это еще один класс в вашей объектной модели. Например, у вас часто будет игрок , потому что у вас есть окрестность с коллекцией игроков , и вы будете перебирать ее, делая что-то для игроки. Или вы начинаете с network объекта. Или (я предполагаю) у вас уже есть игрок от него вы получаете дружбу и вы получаете игрока от него. Таким образом, дружба является фабрикой для игрока объектов, а игрок является фабрикой для дружбы объектов!

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

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

Мой совет : если у вас нет особой причины использовать фабричный объект, не беспокойтесь о них. Просто постройте свои объекты с хорошими конструкторами. Тогда будет естественно добавить свойства, которые возвращают связанные объекты; это будут ваши первые заводы. Это может быть хорошим примером того, как вы не хотите сначала беспокоиться о шаблонах проектирования; шаблоны проектирования не приносят успеха. Ты сделаешь. Шаблоны, как и различные фабричные шаблоны, могут помочь, но не должны заменять базовое объектно-ориентированное мышление.

У вас есть конкретные причины, по которым вам нужны выделенные фабричные объекты?

2 голосов
/ 25 января 2010

KLE правильно обращается с ним по-разному, в зависимости от того, насколько статичны отношения.Я бы добавил, что для классов Factory характерно зеркальное отражение объектной модели.Простой способ представить их как интеллектуальный объект, который знает, как соединять различные классы вашей модели.

2 голосов
/ 25 января 2010

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

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

  1. получить предыдущего родителя ребенка; если не ноль, удалите ребенка из этого старого родителя.
  2. заменить родительское поле в дочернем на новый родительский
  3. добавить ребенка в коллекцию детей нового родителя.

Если что-то меняется , как подклассы, которые следует использовать в каком-то контексте, то вам нужно точно определить, что меняется. Только после того, как вы нашли свою точную потребность, могут появиться правильные шаблоны. : -)

Мы могли бы помочь с последней частью, но вы единственный, кто может предоставить необходимую информацию ...; -)

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