Когда объект A создает / агрегирует / знакомит объект B, должен ли объект A иметь член поля, ссылающийся на объект B? - PullRequest
0 голосов
/ 06 июня 2019

Из шаблона проектирования от GoF:

Ссылка на объект, представляющая отношение части или агрегации, указывается линией со стрелкой в ​​заголовке с ромбом в основании.Стрелка указывает на класс, агрегированный (например, Shape).Линия со стрелкой без ромба обозначает знакомство (например, LineShape сохраняет ссылку на объект Color, который могут иметь другие формы).Имя ссылки может появиться рядом с базой, чтобы отличить ее от других ссылок. Еще одна полезная вещь, которую нужно показать, это то, какие классы определяют , какие другие.Мы используем пунктирную линию со стрелкой для указания этого, поскольку OMT не поддерживает это.Мы называем это «создает» отношения.Стрелка указывает на класс, который создан.На рисунке B.lc CreationTool создает объекты LineShape.

enter image description here

  • , когда объект A агрегирует объект B, объект долженA иметь элемент поля, ссылающийся на объект B?

  • , когда объект A знакомится с объектом B, должен ли объект A иметь элемент поля, ссылающийся на объект B?

  • когда объект A создает экземпляр объекта B, должен ли объект A иметь член поля, ссылающийся на объект B?

1 Ответ

1 голос
/ 07 июня 2019

Instantiation создает экземпляр объекта (для этого во многих языках используется ключевое слово new), а агрегация описывает отношения между объектами (которые уже созданы или созданы).Чтобы избежать путаницы, я должен указать, что все термины, используемые в этом примере, такие как агрегация , используются в контексте Мартина Фаулера, который ввел другое определение или формулировку в отличие от стандартного определения UML.

Из вашей диаграммы:

Агрегация

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

// The `Shape` class
class Shape
{
 ...
}

// The `Drawing`class that aggregates a single `Shape`
class Drawing
{
  // The reference to the instance of `Shape`
  private Shape shape;

  // The constructor
  public Drawing() 
  {
    // Create an instance of `Shape`.
    // Because the relationship between `Drawing`and `Shape`is an aggregation the instantiation occurs inside the owners constructor (opposed to outside the owner object).
    this.shape = new Shape();
  }
}

Поскольку отношение между Drawing и Shape является агрегацией создание экземпляра типа Shape происходит внутри конструктора владельцев (в отличие от внешнего объекта владельца в случае знакомства ).

Знакомство

Другое отношение, которое изображено на диаграмме, это знакомство . Знакомство существует между объектом типа LineShape и Color.Это означает, что LineShape использует a Color.Color будет жить независимо от того, кто владеет LineShape объектом.Пунктирная линия между объектами CreationTool и LineShape описывает создание (создание).Это означает, что CreationTool создает экземпляр LineShape.Это необходимо, поскольку в отличие от агрегация знакомство описывает независимое время жизни обоих объектов.Color может использоваться совместно с другими Shape объектами.Для этого требуется, чтобы связанные объекты LineShape, объект Color, создавались вне владельца (а не внутри конструктора владельца, как в сценарии агрегация ):

// The `LineShape` class
class Color
{
 ...
}

// The `LineShape`class that acquaints or associates with a single `Color`
class LineShape
{
  // The reference to the instance of `Shape`
  private Color color;

  // The constructor
  public LineShape(Color sharedColorInstance) 
  {
    // Request an instance of `Shape` as constuctor parameter.
    // Because the relationship between `LineShape`and `Color`is an acquaintance the instantiation occurs outside the owners constructor  (opposed to inside the owner object).
    this.color = sharedColorInstance;
  }
}


// The `CreationTool` class that creates an instance of `LineShape 
// and passes a shared instance of `Color`into the constructor.
class CreationTool
{
  Color color = new Color();

  // Create the instance of `LineShape` 
  // to satisfy the dashed line (relationship) in the diagramm
  LineShape firstLine = new LineShape(color);

  // To show the benefit of acquaintance a second instance of `LineShape` is created
  // using the same `Color` instance
  LineShape secondLine = new LineShape(color);

  // When firstLine's lifetime ends, 
  // secondLine still has a valid instance of `Color` 
}

Поскольку отношения между LineShape и Color - это знакомство * * * происходит вне конструктора владельцев (в противоположность внутреннему объекту владельца, как в Сценарий агрегации ).Таким образом, один экземпляр Color может использоваться несколькими владельцами.

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

Для создания экземпляров требование поля - это отдельная история.Можно сказать, что когда CreationTool создает экземпляр LineShape, ему не нужно поле для хранения ссылки на этот объект.Но в случае Color CreationToolobject может хранить ссылку на экземпляр Color в поле, чтобы повторно использовать его (делиться им) при создании новых экземпляров LineShape, поскольку экземпляр Color являетсянеобходимо для удовлетворения конструктора LineShape.Поэтому, если поле для хранения ссылки на созданный экземпляр внутри создателя является обязательным, это, во-первых, совершенно необязательно и зависит от контекста.

Следует отметить, что в случае знакомства , другой способ «внедрить» экземпляр принадлежащего объекта - это использовать метод setter:

Color color = new Color();
LineShape shape = new LineShape();
shape.SetColor(color);

Использование конструктора должно быть предпочтительным способом, когда это возможно.

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

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