Практика проектирования для контейнерного класса с несколькими коллекциями, которые ссылаются друг на друга - PullRequest
2 голосов
/ 20 марта 2012

Я пытаюсь спроектировать структуру класса следующим образом:

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

Отношения могут быть «Attacks To», где у стиля есть список других стилей, к которым он может присоединяться, и «Attachments», которое является обратным к этому. Если стиль может «Присоединяться» к другому стилю, тогда другой стиль должен иметь возможность создавать первый стиль в качестве одного из своих «Вложений».

Контейнер управляет Предметами и Стилями Предметов. Я использую уникальные идентификаторы для всего, потому что я хочу иметь возможность сериализации в и из XML.

Однако я продолжаю сталкиваться с логическими проблемами, такими как попытка десериализации ItemStyle из XML, но, конечно, он не может генерировать ссылки на идентификаторы элементов, которые он читает, поскольку только сам Контейнер имеет доступ к другим элементам.

Другая проблема заключается в том, что я хочу, чтобы эти классы были независимы до такой степени, что, если у меня есть ссылка на Item, я могу вызвать список совместимых элементов, таких как вызов «Item.Attachments» или «Item.AttachesTo». Все это, конечно, должно быть рассчитано контейнером, так как это единственный класс, который может иметь доступ как к элементам ItemStyles, так и к коллекциям Item.

Итак, я столкнулся с решением, где мне нужно будет дать каждому Item и ItemStyle ссылку на Контейнер, чтобы они могли выполнять свои собственные поиски и определять свои отношения с другими элементами. Это похоже на плохую инкапсуляцию и плохую практику ООП, но я не могу придумать другого пути.

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

Должно ли следовать модели ListView отношений владельца / предмета работать с моими классами?

1 Ответ

2 голосов
/ 20 марта 2012

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

Я бы предпочел более поздний подход. Тем не менее, одно из того, что я хотел бы сделать, это избежать прямой связи с контейнером. Вместо этого я представлю интерфейс IContainer, который будет абстрагировать результаты поиска, необходимые для детей, а дети (Item / ItemStyle) будут знать только об интерфейсе IContainer.

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

Еще один подход - иметь свободную модель. По сути, Item может поддерживать свои собственные ссылки ItemStyle. При необходимости Container может создавать коллекцию ItemStyle путем реализации шаблона посетителя.

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