Мне было трудно понять разницу между композицией и агрегированием в UML. Может кто-нибудь предложить мне хорошее сравнение и контраст между ними? Я также хотел бы научиться распознавать разницу между ними в коде и / или увидеть короткий пример программного обеспечения / кода.
Изменить: отчасти причина, по которой я спрашиваю, связана с обратной документацией, которую мы делаем на работе. Мы написали код, но нам нужно вернуться и создать диаграммы классов для кода. Мы просто хотим правильно передать ассоциации.
Ответы:
Различие между агрегацией и составом зависит от контекста.
Возьмем пример автомобиля, упомянутый в другом ответе - да, это правда, что выхлоп автомобиля может работать «сам по себе», поэтому он может не входить в состав автомобиля, но это зависит от приложения. Если вы создаете приложение, которое действительно имеет дело с автономными автомобильными выхлопами (приложение для управления автосервисом?), То вам будет лучше агрегировать. Но если это простая гоночная игра, и выхлоп машины служит только частью машины - что ж, композиция будет вполне подходящей.
Шахматная доска? Та же проблема. Шахматная фигура без шахматной доски не существует только в определенных приложениях. В других случаях (например, у производителя игрушек) из шахматной фигуры определенно нельзя составить шахматную доску.
Ситуация становится еще хуже, когда вы пытаетесь сопоставить композицию / агрегирование с вашим любимым языком программирования. В некоторых языках разницу легче заметить («по ссылке» или «по значению», когда все просто), но в других может вообще не существовать.
И последний совет? Не тратьте слишком много времени на этот вопрос. Это того не стоит. Это различие вряд ли полезно на практике (даже если у вас есть полностью четкая «композиция», вы все равно можете захотеть реализовать ее как агрегирование по техническим причинам - например, из-за кеширования).
источник
Как правило большого пальца:
class Person { private Heart heart; private List<Hand> hands; } class City { private List<Tree> trees; private List<Car> cars }
В композиции (Человек, Сердце, Рука) «подобъекты» (Сердце, Рука) будут уничтожены, как только будет уничтожен Человек.
В совокупности (Город, Дерево, Автомобиль) «подобъекты» (Дерево, Автомобиль) НЕ будут уничтожены при разрушении Города.
Суть в том, что композиция делает упор на взаимное существование, и в совокупности это свойство НЕ требуется.
источник
Состав и агрегирование - это типы ассоциаций. Они очень тесно связаны, и с точки зрения программирования, похоже, между ними нет большой разницы. Я постараюсь объяснить разницу между этими двумя примерами java-кода.
Агрегация : объект существует вне другого, создается снаружи, поэтому он передается в качестве аргумента (например) конструктору. Пример: Люди - машина. Автомобиль создается в другом контексте и затем становится собственностью человека.
// code example for Aggregation: // reference existing HttpListener and RequestProcessor public class WebServer { private HttpListener listener; private RequestProcessor processor; public WebServer(HttpListener listener, RequestProcessor processor) { this.listener = listener; this.processor = processor; } }
Композиция : объект существует или имеет смысл только внутри другого, как часть другого. Пример: Люди - сердце. Вы не создаете сердце, а затем передаете его человеку. Вместо этого, когда создается человек, создается сердце.
// code example for composition: // create own HttpListener and RequestProcessor public class WebServer { private HttpListener listener; private RequestProcessor processor; public WebServer() { this.listener = new HttpListener(80); this.processor = new RequestProcessor(“/www/root”); } }
Объясняется здесь на примере Различия между агрегированием и композицией
источник
Композиция подразумевает, что дочерние объекты разделяют продолжительность жизни с родительскими. Агрегация - нет. Например, шахматная доска состоит из шахматных квадратов - шахматных квадратов без доски на самом деле не существует. Однако автомобиль - это совокупность частей: выхлоп автомобиля остается выхлопом автомобиля, если он не является частью автомобиля в то время.
источник
Пример, который я усвоил, - пальцы на руке. Ваша рука состоит из пальцев. Он им владеет. Если рука умирает, умирают пальцы. Вы не можете «объединить» пальцы. Вы не можете просто взять лишние пальцы, прикрепить и отсоединить их от руки по своему желанию.
Ценность здесь, с точки зрения дизайна, часто связана со сроком службы объекта, как сказал другой плакат. Допустим, у вас есть клиент и у него есть учетная запись. Эта Учетная запись является «составным» объектом клиента (по крайней мере, в большинстве контекстов, которые я могу придумать). Если вы удалите Клиента, Учетная запись не будет иметь самостоятельной ценности, поэтому она также будет удалена. При создании объекта часто бывает наоборот. Поскольку Учетная запись имеет значение только в контексте Клиента, у вас будет создание Учетной записи как часть создания Клиента (или, если вы делаете это лениво, это будет частью некоторой транзакции Клиента).
В дизайне полезно подумать о том, какие объекты владеют (составляют) другие объекты, а какие просто ссылаются (объединяют) другие объекты. Это может помочь определить, где лежит ответственность за создание / очистку / обновление объекта.
Что касается кода, то часто сложно сказать. Почти все в коде является ссылкой на объект, поэтому может быть неочевидно, состоит ли объект, на который ссылается, (принадлежит) или агрегирован.
источник
Удивительно, как много путаницы существует в отношении различия между агрегированием и составом концепций ассоциации « часть – целое». . Основная проблема - это широко распространенное заблуждение (даже среди опытных разработчиков программного обеспечения и среди авторов UML), что концепция композиции подразумевает зависимость жизненного цикла между целым и его частями, так что части не могут существовать без целого. Но эта точка зрения игнорирует тот факт, что бывают также случаи ассоциаций части и целого с неделимыми частями, когда части могут быть отделены от целого и пережить разрушение целого.
В документе спецификации UML определение термина «композиция» всегда подразумевало не разделяемые части, но не было ясно, что является определяющей характеристикой «композиции», а что является просто необязательной характеристикой. Даже в новой версии (по состоянию на 2015 год), UML 2.5, после попытки улучшить определение термина «композиция», он остается неоднозначным и не дает никаких указаний по моделированию частично целых ассоциаций с не разделяемыми части, в которых части могут быть отделены от целого и выдерживают разрушение целого, в отличие от случая, когда части не могут быть отделены и разрушаются вместе с целым. Они говорят
Но в то же время говорят
Эта путаница указывает на неполноту определения UML, которое не учитывает зависимости жизненного цикла между компонентами и композитами. Поэтому важно понимать, как определение UML может быть улучшено путем введения стереотипа UML для « неотделимых» композиций, когда компоненты не могут быть отделены от их композиции и, таким образом, должны уничтожаться всякий раз, когда их композиция разрушается.
Сочинение
Как объяснил Мартин Фаулер , главная проблема для характеристики композиции состоит в том, что «объект может быть только частью одного отношения композиции». Это также объясняется в отличном сообщении блога « Состав UML против агрегирования против ассоциации » Гирта Беллекенса. В дополнение к этой определяющей характеристике композиции (иметь эксклюзивные или не подлежащие совместному использованию части) композиция также может иметь зависимость жизненного цикла между композитом и его компонентами. На самом деле существует два вида таких зависимостей:
Person
иHeart
, показанная на диаграмме ниже. Сердце либо разрушается, либо пересаживается другому человеку, когда его владелец умирает.Person
иBrain
.Таким образом, зависимости жизненного цикла применимы только к конкретным случаям композиции, но не в целом, поэтому они не являются определяющей характеристикой.
Спецификация UML гласит: «Часть может быть удалена из составного экземпляра до того, как будет удален составной экземпляр, и, следовательно, не может быть удалена как часть составного экземпляра». В примере композиции
Car
-Engine
, как показано на следующей диаграмме, очевидно, что двигатель может быть отсоединен от автомобиля до того, как автомобиль будет разрушен, и в этом случае двигатель не будет разрушен и может быть использован повторно. Это подразумевается нулевой или одной кратностью на составной стороне линии композиции.Кратность конца ассоциации композиции , по меньшей композиционной стороне равна 1 или 0..1, в зависимости от того , если компоненты имеют обязательный композит (должно быть присоединены к составному) или нет. Если компоненты неразделимы , это означает, что они имеют обязательную композицию.
Агрегация
Агрегация - это еще одна особая форма ассоциации с предполагаемым значением отношения «часть – целое», когда части целого могут быть разделены с другими целыми. Например, мы можем смоделировать агрегацию между классами
DegreeProgram
иCourse
, как показано на следующей диаграмме, поскольку курс является частью программы на получение степени, и курс может быть разделен между двумя или более программами получения степени (например, степень инженера может совместно использовать C курс программирования со степенью информатики).Однако концепция агрегации с разделяемыми частями на самом деле не имеет большого значения, поэтому она не имеет никаких последствий для реализации, и поэтому многие разработчики предпочитают не использовать белый ромб в своих диаграммах классов, а просто моделировать простую ассоциацию. вместо. Спецификация UML гласит: «Точная семантика совместной агрегации зависит от области приложения и разработчика».
Кратность конца ассоциации агрегации по крайней всей стороне может быть любое число (*) , так как часть может принадлежать или совместно среди, любого количества целостностей.
источник
В терминах кода композиция обычно предполагает, что содержащий объект отвечает за создание экземпляров компонента *, а содержащий объект содержит только долгоживущие ссылки на него. Таким образом, если ссылка на родительский объект прекращается и происходит сборка мусора, то же самое произойдет и с дочерним объектом.
так что этот код ...
Class Order private Collection<LineItem> items; ... void addOrderLine(Item sku, int quantity){ items.add(new LineItem(sku, quantity)); } }
предполагает, что LineItem является компонентом Order - LineItems не существуют вне порядка, в котором они содержатся. Но объекты Item не создаются в порядке - они передаются по мере необходимости и продолжают существовать, даже если в магазине нет заказов. поэтому они связаны, а не компоненты.
* nb контейнер отвечает за создание экземпляра компонента, но он может не вызывать сам new ... () - это java, обычно сначала нужно пройти через фабрику или две!
источник
Концептуальные иллюстрации, представленные в других ответах, полезны, но я хотел бы поделиться еще одним важным моментом.
Я получил некоторый опыт использования UML для генерации кода, для исходного кода или DDL для реляционной базы данных. Здесь я использовал композицию, чтобы указать, что таблица имеет внешний ключ, не допускающий значения NULL (в базе данных), и не допускающий значения NULL «родительский» (и часто «конечный») объект в моем коде. Я использую агрегацию, когда я хочу, чтобы запись или объект могли существовать как «сирота», не прикрепляться ни к какому родительскому объекту или быть «усыновленными» другим родительским объектом.
Другими словами, я использовал обозначение композиции как сокращение, чтобы обозначить некоторые дополнительные ограничения, которые могут потребоваться при написании кода для модели.
источник
Пример, который мне нравится: Состав: Вода - часть пруда. (Пруд представляет собой состав воды.) Агрегация: Пруд имеет утки и рыбы (в пруду - утки и рыба).
Как вы можете видеть, я выделил жирным шрифтом «часть из» и «имеет», поскольку эти две фразы обычно указывают на то, какая связь существует между классами.
Но, как указывали другие, во многих случаях, является ли соединение композицией или агрегацией, зависит от приложения.
источник
Так сложно провести различие между совокупным отношением и составным отношением, но я собираюсь привести несколько примеров: у нас есть дом и комнаты, здесь у нас есть составное отношение, комната - это часть дома, и жизнь в комнате началась. с домашней жизнью и завершится, когда жизнь в доме закончится, комната - это часть дома, мы говорим о композиции, например, о стране и столице, книге и страницах. В качестве примера совокупного отношения возьмите команду и игроков, игрок может существовать без команды, а команда - это группа игроков, и жизнь игрока может начаться раньше жизни команды, если мы говорим о программировании, мы можем создавать игроков и после того, как мы создадим команду, но для композиции №, мы создаем комнаты внутри дома. Композиция ----> композит | составление. Агрегация -------> группа | элемент
источник
Установим сроки. Агрегация - это метатерм в стандарте UML, который означает ОБА композицию и общую агрегацию, называемую просто shared . Часто это неправильно называют «агрегацией». Это ПЛОХО, потому что композиция - это тоже агрегирование. Насколько я понимаю, вы имеете в виду «общий».
Дополнительно от стандарта UML:
Итак, ассоциация университета и кафедры - это композиция, потому что кафедра не существует вне университета (ИМХО).
Т.е. все остальные ассоциации могут быть нарисованы как общие агрегаты, если вы следуете только каким-то своим или чужим принципам. Также смотрите здесь .
источник
Рассмотрим такие части человеческого тела, как почки, печень, мозг. Если мы попытаемся отобразить здесь концепцию композиции и агрегации, это будет примерно так:
До появления трансплантации частей тела, таких как почки и печень, эти две части тела входили в состав человеческого тела и не могли существовать изолированно от человеческого тела.
Но после появления трансплантации частей тела их можно пересаживать в другое человеческое тело, поэтому эти части находятся в совокупности с человеческим телом, поскольку теперь их существование изолированно от человеческого тела возможно.
источник