Считается ли связь внутри объекта анти-паттерном? - PullRequest
5 голосов
/ 23 мая 2011

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

Например:

   public class Item
   {
       private Item prev; 
       private Item next;
       ...
   }

Часто цитируемая рекомендация состоит в том, чтобы просто использовать универсальныйКонтейнерный класс (например, java.util.LinkedList в Java), но это создает дополнительные издержки, связанные с наличием отдельного объекта узла (и связанный объект не может легко ссылаться на своих братьев и сестер).

Мысли?

Ответы [ 8 ]

2 голосов
/ 23 мая 2011

Это не обязательно анти-паттерн.Анти-паттерны должны иметь негативные побочные эффекты, чтобы получить право на «анти».

Например, Node в Tree структуре данных потребуется , это кешируется связьвнутри Node.Все остальное нарушит гораздо более важную концепцию инкапсуляции и локализации данных и кода, основанную на ответственности объекта.

С другой стороны, структура данных Customer, в которую встроен «следующий» клиент, подразумеваетчто структура данных Customer выполняет две несвязанные обязанности: поддержку данных Customer и поддержку структуры данных списка Customer.В таком сценарии две обязанности могут смешиваться таким образом, что это влияет на простоту обслуживания;и, следовательно, будет рассматриваться как анти-шаблон.

2 голосов
/ 23 мая 2011

Я полагаю, что классы XML DOM в java делают (что-то вроде) то, что вы описываете, так что есть по крайней мере прецедент для этого. В общем, то, что вы описываете, вероятно, является исключением, а не правилом, потому что в противном случае вы просто в конечном итоге повторно реализуете связанный список.

2 голосов
/ 23 мая 2011

Как правило, это рекомендуется из-за ползучести функций, которые понадобятся вам в будущем. Даже если вам не нужны такие функции, как «поиск» и «сортировка», в один прекрасный день спецификации изменятся, и вам нужно будет отсортировать свои элементы. Если вы реализуете это таким образом, теперь вам нужно реализовать сортировку.

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

Кроме того, ваше беспокойство по поводу накладных расходов на дополнительный объектный узел на самом деле не должно быть слишком большим беспокойством - насколько это может быть дополнительная нагрузка? В такие дни, как сегодня, даже если бы они были килобайтами (которые были бы сумасшедшими ), это не должно было составлять беспокойства.

2 голосов
/ 23 мая 2011

Это анти-шаблон, если он не всегда , используемый в связанном списке. Вы получите швейцарскую армию, если добавите в свои классы свойства / методы, которые вам могут понадобиться . Читать о YAGNI .

Добавление этих методов также нарушит SRP, поскольку элемент также будет отвечать за отслеживание своих братьев и сестер.

2 голосов
/ 23 мая 2011

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

Иногда немногонакладные расходы - это стоимость «более чистых» конструкций.Готовы ли вы платить за эти накладные расходы, это другой вопрос.На мой взгляд, небольшие накладные расходы, добавленные с помощью утилит, таких как встроенные связанные списки, стоят того ... они экономят время разработки, тщательно тестируются и обеспечивают более чистый дизайн.

1 голос
/ 23 мая 2011

Как всегда, зависит от масштаба вашего проекта и / или от контекста, в котором это используется. Если проект довольно маленький, то следование всем рекомендациям по хорошей практике не будет очень полезным: вы просто потратите больше времени на то, чтобы сделать его «должным образом», и выгоды могут быть почти нулевыми.

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

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

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

1 голос
/ 23 мая 2011

Этот шаблон называется инвазивным контейнером .

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

1 голос
/ 23 мая 2011

В Java это меньше проблем, чем в других языках, поскольку Item должен быть указателем класса. Если, с другой стороны, Item является структурой, как это возможно в C # и других языках, вы сталкиваетесь с очевидными проблемами. Помимо того, что у вас есть изменяемая структура, вы также, вероятно, получите ошибку во время компиляции, пытаясь определить структуру с бесконечно большим требованием к памяти.

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

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