Могут ли экземпляры или объекты любого класса рассматриваться как атрибуты другого класса?

Читая книгу Крейга Лармана (Применение UML и шаблонов;...), я заметил, что он добавил экземпляры класса Die в качестве атрибутов в класс DiceGame.


Изображение частичной диаграммы классов DiceGame.


Является ли это возможным? и есть много связанных вопросов по программированию, где они отрицают сделать это.


person M.D Shaw    schedule 30.05.2016    source источник
comment
Я понятия не имею, почему это было названо неясным. У ОП, очевидно, было некоторое недопонимание об экземплярах. Но эй, мы здесь, чтобы прояснить такие вопросы.   -  person qwerty_so    schedule 30.05.2016
comment
Я тоже думал, что это относительно ясно. У меня нет права голоса, иначе я бы помог отменить это.   -  person Jim L.    schedule 31.05.2016


Ответы (5)


Я бы изменил вопрос на "Могут ли ссылки на любой класс рассматриваться как атрибуты в другом классе?" Технически ответ «да», но вы не должны моделировать это таким образом в UML. Вы должны моделировать простые значения как атрибуты (внутри прямоугольника класса), а непростые ссылки моделировать как ассоциации. Простые значения идентифицируются только их значениями (например, число 5), тогда как непростые ссылки указывают на вещи с идентичностью. В вашем случае каждый Die должен иметь идентификатор, отличный от его текущей номинальной стоимости. Следовательно, вы не должны моделировать атрибуты типа Die, вы должны моделировать свойство в конце ассоциации.

На опубликованной вами диаграмме есть три (!!) свойства типа Die. Один называется die1, один называется die2, а третий безымянный с кратностью 2. На языке программирования это дало бы вам четыре места для хранения ссылок на игральные кости, что явно неверно.

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

введите здесь описание изображения

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

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

person Jim L.    schedule 31.05.2016

Это не экземпляры Die, а просто два свойства типа Die. На картинке не очень удачное использование UML (позор Ларману). Связь между DiceGame и Die использует кратность 2. И, скорее всего, он имеет в виду die1 и die2. Но это было бы угадыванием. Лучшее обозначение было бы

введите здесь описание изображения

с соответствующими именами конца ассоциации.

person qwerty_so    schedule 30.05.2016
comment
Я так и собирался ответить, но ты меня опередил. Однако я бы, вероятно, сделал ассоциации однонаправленными, если только кубик по какой-то причине не является асинхронным и посылает сигналы обратно в игру. - person Jim L.; 30.05.2016
comment
@ДжимЛ. Я должен дать вам немного больше времени :-) Честно говоря, у меня очень много свободного времени, так что я на скоростной полосе. Однако ваши ответы часто более обстоятельно выражены, чем мои. К сожалению, закрыли этот. Мне это было ничуть не непонятно. Я проголосую за повторное открытие, чтобы вы могли ответить, и я заберу свой обратно. - person qwerty_so; 30.05.2016
comment
Спасибо за добрые мысли, Томас! ???? - person Jim L.; 31.05.2016
comment
@ДжимЛ. Итак, он снова открыт. Не стесняйтесь опубликовать свой ответ :-) - person qwerty_so; 31.05.2016
comment
@ThomasKilian, не могли бы вы порекомендовать другую лучшую книгу для OOA/D? - person M.D Shaw; 31.05.2016
comment
Кто-то еще только что спросил, и я порекомендовал Дуга Розенберга и ICONIX, которые помогли мне около 15 лет назад. Это был видеоурок вместе с моделью Sparx EA. Не знаю, доступно ли это еще. - person qwerty_so; 31.05.2016

Краткий ответ: да... и это случается очень часто.

В объектно-ориентированной архитектуре есть изящный маленький трюк, позволяющий выяснить, должен ли класс содержать свойство какого-либо другого типа класса: "Is-A" и "Has-A".

В этом случае у вас есть класс DiceGame. Вы спрашиваете себя: «Является ли DiceGame кубиком» или DiceGame «Has-A» умирает. Если ответ первый, то вы используете наследование, в противном случае вы устанавливаете его как свойство (я), как в опубликованном вами примере.

Если бы у вас был другой класс под названием «GamblingRoom», наличие DiceGame свойства этого класса «GamblingRoom» «могло бы» быть жизнеспособным решением... конечно, в зависимости от того, что вам нужно делать.

Вот лучшее объяснение этого в вопросе, аналогичном тому, что у вас есть ... но, вероятно, лучше объяснено, чем то, что я сделал здесь;)

терминология HAS-A, IS-A в объектно-ориентированном языке

person dvsoukup    schedule 31.05.2016
comment
Как этот ответ относится к вопросу? - person Jim L.; 31.05.2016
comment
@ДжимЛ. Как это было сделано, объяснено хорошо, особенно мне помогли термины HAS-A и IS-A. - person M.D Shaw; 31.05.2016
comment
@JimL. Вы спросили, возможно ли это. Я дал вам ответ плюс немного больше, чтобы понять, почему это так ... и терминология «есть-есть-а» может помочь вам понять это. - person dvsoukup; 31.05.2016

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

person Frank Puffer    schedule 30.05.2016

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

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

person nirali.gandhi    schedule 30.05.2016