Следующее указывает на плохой дизайн? - PullRequest
2 голосов
/ 05 июня 2010

Мне было интересно, думаете ли вы, что следующий код обычно указывает на плохой дизайн ...

class X
{
public:
  ...
private:
  Y y;
};

Class Y
{
public:
   Y( X& value ){ x = value; };
private:
   X& x;
}

(т.е. существует некоторая циклическая зависимость между классами X и Y).

Ответы [ 5 ]

7 голосов
/ 05 июня 2010

Зависит от того, что вы пытаетесь сделать. Некоторые конструкции, такие как итераторы, требуют таких циклов.

4 голосов
/ 05 июня 2010

Нет, я не думаю, что это плохой дизайн. Это похоже на отношения родитель-потомок (то есть 1-к-1), где у дочернего элемента есть указатель на родителя.

Основная причина такого дизайна заключается в том, что кто-то может получить ссылку на Y без указания X. Если весь доступ к Y осуществляется только через X, такая ссылка более сомнительна.

Как указывает Билли ONeal, одним из примеров может быть итератор, который должен иметь возможность ссылаться на коллекцию, которой он принадлежит. Это может сделать возможным создание итератора в массиве, который не нужно аннулировать при изменении размера массива, поскольку он будет проверять текущий адрес буфера массива и текущий размер при каждом доступе.

Другим примером может быть класс OrderLine (ваш X), который содержит ссылку на элемент, количество и т. Д. Он также имеет необязательный элемент типа DigitalLicense (ваш Y). DigitalLicense содержит большое зашифрованное описание лицензии, поэтому оно включено только в те OrderLines, которые соответствуют продукту с цифровой лицензией.

В процессе строительства ссылка на DigitalLicense также помещается в отдельную карту с указанием идентификатора лицензии. Теперь можно искать DigitalLicense на основе идентификатора лицензии на карте. Затем обратная ссылка используется для перехода от DigitalLicense к OrderLine. Если у OrderLine есть аналогичная обратная ссылка, можно также вернуться к Order.

2 голосов
/ 05 июня 2010

в прежние времена, например в VB6 это был плохой дизайн, потому что VB не мог удалить оба объекта, где один ссылался на другой, и наоборот. поскольку C ++ не имеет подсчета ссылок, это больше не проблема.

1 голос
/ 05 июня 2010

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

1 голос
/ 05 июня 2010

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

...