Qual é a diferença entre associação, agregação e composição?

Qual é a diferença entre associação, agregação e composição? Por favor, explique em termos de implementação.

  • Associação é um relacionamento em que todos os objects têm seu próprio ciclo de vida e não há proprietário.

    Vamos dar um exemplo de professor e aluno. Vários alunos podem se associar a um único professor e um único aluno pode se associar a vários professores, mas não há propriedade entre os objects e ambos têm seu próprio ciclo de vida. Ambos podem ser criados e excluídos de forma independente.

  • A agregação é uma forma especializada de associação na qual todos os objects têm seu próprio ciclo de vida, mas há propriedade e os objects filhos não podem pertencer a outro object pai.

    Vamos dar um exemplo de departamento e professor. Um único professor não pode pertencer a vários departamentos, mas se excluirmos o departamento, o object do professor não será destruído. Podemos pensar nisso como um relacionamento “tem um”.

  • A composição é novamente uma forma especializada de Agregação e podemos chamar isso de relacionamento de “morte”. É um tipo forte de agregação. O object filho não tem seu ciclo de vida e, se o object pai for excluído, todos os objects filhos também serão excluídos.

    Vamos dar novamente um exemplo de relacionamento entre House e Rooms. Casa pode conter várias salas – não há vida independente do quarto e qualquer sala não pode pertencer a duas casas diferentes. Se excluirmos, a sala da casa será automaticamente excluída.

    Vamos dar outro exemplo de relacionamento entre perguntas e opções. As perguntas individuais podem ter várias opções e a opção não pode pertencer a várias perguntas. Se excluirmos as perguntas, as opções serão automaticamente excluídas.

Para dois objects, Foo e Bar os relacionamentos podem ser definidos

Associação – Eu tenho um relacionamento com um object. Foo usa Bar

 public class Foo { void Baz(Bar bar) { } }; 

Composição – Eu possuo um object e sou responsável por sua vida útil, quando Foo morre, o mesmo acontece com o Bar

 public class Foo { private Bar bar = new Bar(); } 

Agregação – Eu tenho um object que eu peguei emprestado de outra pessoa. Quando Foo morre, Bar pode viver.

 public class Foo { private Bar bar; Foo(Bar bar) { this.bar = bar; } } 

Eu sei que esta questão é marcada como C #, mas os conceitos são questões bastante genéricas como este redirecionamento aqui. Então eu vou fornecer o meu ponto de vista aqui (um pouco tendencioso do ponto de vista java, onde eu estou mais confortável).

Quando pensamos em natureza orientada a objects, sempre pensamos em objects, class (projetos de objects) e a relação entre eles. Objetos são relacionados e interagem entre si através de methods. Em outras palavras, o object de uma class pode usar serviços / methods fornecidos pelo object de outra class. Esse tipo de relacionamento é denominado como associação. .

Agregação e Composição são subconjuntos de associação, o que significa que eles são casos específicos de associação.

insira a descrição da imagem aqui

  • Tanto no object de agregação e composição de uma class “possui” object de outra class .
  • Mas há uma diferença sutil. Em Composição, o object da class que pertence ao object de sua class proprietária não pode viver por conta própria (também chamado de “relação de morte”). Ele sempre viverá como parte de seu object proprietário onde, como em Aggregation, o object dependente é autônomo e pode existir mesmo se o object da class proprietária estiver morto.
  • Portanto, na composição, se possuir object for garbage collected, o object de propriedade também será o que não é o caso na agregação.

Confuso?

Exemplo de composição : considere o exemplo de um carro e um mecanismo muito específico para esse carro (o que significa que ele não pode ser usado em nenhum outro carro). Esse tipo de relação entre Car e class SpecificEngine é chamado de Composition. A class Object of Car não pode existir sem o object da class SpecificEngine e o object de SpecificEngine não tem significado sem a class Car. Para colocar em palavras simples, a class Car unicamente “possui” a class SpecificEngine.

Exemplo de Agregação : Agora considere a class Car e class Wheel . O carro precisa de um object Wheel para funcionar. Significado Objeto de carro próprio Objeto de roda, mas não podemos dizer Objeto de roda não tem significado sem object de carro. Pode muito bem ser usado em uma bicicleta, caminhão ou object de carros diferentes.

Resumindo –

Resumindo, a associação é um termo muito genérico usado para representar quando a class usou as funcionalidades fornecidas por outra class. Dizemos que é composição se um object de class pai possui outro object de class filho e esse object de class filho não pode existir significativamente sem o object de class pai. Se puder, então é chamado de Agregação.

Mais detalhes aqui.

Associação é um conceito generalizado de relações. Inclui Composição e Agregação.

Composição ( mistura ) é uma maneira de agrupar objects simples ou tipos de dados em uma única unidade . As composições são um bloco de construção crítico de muitas estruturas básicas de dados

Agregação ( coleção ) difere da composição ordinária na medida em que não implica em propriedade. Na composição, quando o object proprietário é destruído, os objects contidos também são. Em agregação, isso não é necessariamente verdade.

Ambos denotam relação entre object e diferem apenas em sua força.

insira a descrição da imagem aqui

Agora vamos observar a seguinte imagem

relações

insira a descrição da imagem aqui

Analogia:

Composição : A imagem a seguir é a composição da imagem, ou seja, o uso de imagens individuais que formam uma imagem.
insira a descrição da imagem aqui

Agregação : coleção de imagens em um único local

insira a descrição da imagem aqui

Por exemplo, uma universidade possui vários departamentos e cada departamento tem vários professores. Se a universidade fechar, os departamentos não existirão mais, mas os professores desses departamentos continuarão a existir. Portanto, uma universidade pode ser vista como uma composição de departamentos, enquanto os departamentos têm uma agregação de professores. Além disso, um professor poderia trabalhar em mais de um departamento, mas um departamento não poderia fazer parte de mais de uma universidade.

De um post de Robert Martin no comp.object :

Associação representa a capacidade de uma instância enviar uma mensagem para outra instância. Isso geralmente é implementado com um ponteiro ou variável de instância de referência, embora também possa ser implementado como um argumento de método ou a criação de uma variável local.

 //[Example:] //|A|----------->|B| class A { private: B* itsB; }; 

Agregação […] é o relacionamento típico de todo / parte. Isso é exatamente o mesmo que uma associação, com a exceção de que as instâncias não podem ter relacionamentos de agregação cíclica (ou seja, uma parte não pode conter todo).

 //[Example:] //|Node|<>-------->|Node| class Node { private: vector itsNodes; }; 

O fato de isso ser agregação significa que as instâncias do Node não podem formar um ciclo. Portanto, esta é uma Árvore de Nós e não um gráfico de Nós.

Composição […] é exatamente como Agregação, exceto que o tempo de vida da ‘parte’ é controlado pelo ‘todo’. Esse controle pode ser direto ou transitivo. Isto é, o “todo” pode assumir responsabilidade direta pela criação ou destruição da “parte”, ou pode aceitar uma parte já criada, e depois passá-la para algum outro todo que assuma a responsabilidade por ela.

 //[Example:] //|Car|<#>-------->|Carburetor| class Car { public: virtual ~Car() {delete itsCarb;} private: Carburetor* itsCarb }; 

Dependência (referências)
Isso significa que não há link conceitual entre dois objects. Por exemplo, o object EnrollmentService faz referência a objects Student & Course (como parâmetros de método ou tipos de retorno)

 public class EnrollmentService { public void enroll(Student s, Course c){} } 

Associação (has-a)
Isso significa que quase sempre há um link entre os objects (eles estão associados). Objeto de pedido tem um object Customer

 public class Order { private Customer customer } 

Agregação (tem + uma parte inteira)
Tipo especial de associação onde existe relação de toda a parte entre dois objects. eles podem viver sem o outro embora.

 public class PlayList{ private List songs; } 

Nota: a parte mais complicada é distinguir a agregação da associação normal. Honestamente, acho que isso está aberto a diferentes interpretações.

Composição (tem + a + parte inteira + propriedade)
Tipo especial de agregação. Um Apartment é composto de alguns Room s. Um Room não pode existir sem um Apartment . quando um apartamento é excluído, todas as salas associadas também são excluídas.

 public class Apartment{ private Room bedroom; public Apartment() { bedroom = new Room(); } } 

Como outros disseram, uma associação é uma relação entre objects, agregação e composição são tipos de associação.

Do ponto de vista da implementação, uma agregação é obtida tendo um membro de class por referência . Por exemplo, se a class A agrega um object da class B, você terá algo parecido com isto (em C ++):

 class A { B & element; // or B * element; }; 

A semântica da agregação é que quando um object A é destruído, o object B que ele está armazenando ainda existe. Ao usar composição, você tem um relacionamento mais forte, geralmente armazenando o membro por valor :

 class A { B element; }; 

Aqui, quando um object A é destruído, o object B que ele contém também será destruído. A maneira mais fácil de conseguir isso é armazenando o membro por valor, mas você também pode usar algum ponteiro inteligente ou excluir o membro no destruidor:

 class A { std::auto_ptr element; }; class A { B * element; ~A() { delete B; } }; 

O ponto importante é que, em uma composição, o object contêiner possui o contido, enquanto que, em agregação, faz referência a ele.

É incrível a quantidade de confusão existente sobre a distinção entre os três conceitos de relacionamento associação , agregação e composição .

Observe que os termos agregação e composição foram usados ​​na comunidade C ++, provavelmente por algum tempo antes de terem sido definidos como casos especiais de associação em diagramas de class UML.

O principal problema é o mal-entendido generalizado e contínuo (mesmo entre desenvolvedores especialistas) de que o conceito de composição implica uma dependência do ciclo de vida entre o todo e suas partes, de modo que as partes não possam existir sem o todo, ignorando o fato de existirem casos de associações de partes inteiras com partes não compartilháveis ​​em que as partes podem ser separadas e sobreviver à destruição do todo.

Tanto quanto eu posso ver, essa confusão tem duas raízes:

  1. Na comunidade C ++, o termo “agregação” foi usado no sentido de uma class que define um atributo para referenciar objects de outra class independente (ver, por exemplo, [1]), que é o senso de associação em Diagramas de Classes UML. O termo “composição” foi usado para classs que definem objects de componentes para seus objects, de tal forma que, na destruição do object composto, esses objects componentes também estão sendo destruídos.

  2. Nos Diagramas de Classes UML, tanto “agregação” quanto “composição” foram definidos como casos especiais de associações representando relações parte-todo (que foram discutidas em filosofia por um longo tempo). Em suas definições, a distinção entre uma “agregação” e uma “composição” é baseada no fato de permitir o compartilhamento de uma parte entre dois ou mais conjuntos. Eles definem “composições” como tendo partes não compartilháveis ​​(exclusivas), enquanto “agregações” podem compartilhar suas partes. Além disso, eles dizem algo como o seguinte: muitas vezes, mas não em todos os casos, as composições vêm com uma dependência do ciclo de vida entre o todo e suas partes, de modo que as partes não podem existir sem o todo.

Assim, enquanto a UML colocou os termos “agregação” e “composição” no contexto correto (de relacionamentos parte-todo), eles não conseguiram defini-los de maneira clara e inequívoca, capturando as intuições dos desenvolvedores. No entanto, isso não é surpreendente, porque há tantas propriedades diferentes (e nuances de implementação) que esses relacionamentos podem ter, e os desenvolvedores não concordam em como implementá-los.

Veja também minha resposta estendida à questão da SO de abril de 2009 listada abaixo.

E a propriedade que foi assumida para definir “composição” entre objects OOP na comunidade C ++ (e essa crença ainda é amplamente mantida): a dependência do ciclo de vida em tempo de execução entre os dois objects relacionados (o composto e seu componente) é não é realmente característico para “composição” porque podemos ter tais dependencies devido à integridade referencial também em outros tipos de associações.

Por exemplo, o seguinte padrão de código para “composição” foi proposto em uma resposta SO :

 final class Car { private final Engine engine; Car(EngineSpecs specs) { engine = new Engine(specs); } void move() { engine.work(); } } 

O entrevistado afirmou que seria característico para “composição” que nenhuma outra class pudesse referenciar / conhecer o componente. No entanto, isso certamente não é verdade para todos os possíveis casos de “composição”. Em particular, no caso do motor de um carro, o fabricante do carro, possivelmente implementado com a ajuda de outra class, pode ter que referenciar o motor para poder entrar em contato com o proprietário do carro sempre que houver um problema com ele.

[1] http://www.learncpp.com/cpp-tutorial/103-aggregation/

Apêndice – Lista incompleta de perguntas feitas repetidamente sobre composição versus agregação no StackOverflow

[ Abr 2009 ]
Agregação versus Composição [fechada como basicamente baseada em opinião por]
[ Abr 2009 ]
Qual é a diferença entre o relacionamento Composição e Associação? [ Maio de 2009 ]
Diferença entre associação, agregação e composição
[ Maio de 2009 ]
Qual é a diferença entre composição e agregação? [duplicado]
[ Out 2009 ]
Qual é a diferença entre agregação, composição e dependência? [marcado como duplicado]
[ Nov 2010 ]
Associação vs. Agregação [marcada como duplicada]
[ Ago 2012 ]
Diferença de implementação entre agregação e composição em Java
[ Fev 2015 ]
UML – associação ou agregação (fragments de código simples)

Associação

A associação representa o relacionamento entre duas classs. Ela pode ser unidirecional (unidirecional) ou bidirecional (bidirecional)

por exemplo:

  1. unidirecional

Cliente faz pedidos

  1. bidirecional

A é casado com B

B é casado com A

Agregação

Agregação é um tipo de associação.Mas com características específicas.Aggregação é o relacionamento em uma grande “todo” class contém uma ou mais “partes” menores classs.Conversely, uma pequena “parte” da class é uma parte de “todo” maior class .

por exemplo:

clube tem sócios

Um clube (“todo”) é composto por vários sócios do clube (“partes”). Os sócios têm vida fora do clube. Se o clube (“todo”) morresse, os membros (“partes”) não morreriam com ele. Porque o membro pode pertencer a vários clubes (“todo”).

Composição

Esta é uma forma mais forte de agregação. “Todo” é responsável pela criação ou destruição de suas “partes”

Por exemplo:

Uma escola tem departamentos

Neste caso, a escola (“todo”) deveria morrer, o departamento (“partes”) morreria com ela. Porque cada parte pode pertencer a apenas um “todo”.

É importante entender por que devemos nos preocupar em usar mais de uma vez uma linha de relacionamento. A razão mais óbvia é descrever o relacionamento pai-filho entre classs (quando o pai excluído é excluído como resultado), mas com mais impotência queremos distinguir associação simples e composição para colocar restrições implícitas na visibilidade e Propagação de mudanças nas classs relacionadas, uma questão que desempenha um papel importante na compreensão e redução da complexidade do sistema.

Associação

A maneira mais abstrata de descrever o relacionamento estático entre classs é usando o link Association, que simplesmente afirma que existe algum tipo de link ou dependência entre duas classs ou mais.

Associação Fraca

A class A pode estar vinculada à ClassB para mostrar que um de seus methods inclui o parâmetro da instância ClassB ou retorna a instância da ClassB.

Associação forte

A class A também pode ser vinculada à ClassB para mostrar que contém uma referência à instância ClassB.

Agregação (Associação Compartilhada)

Nos casos em que há uma parte do relacionamento entre ClassA (whole) e ClassB (part), podemos ser mais específicos e usar o link de agregação em vez do link de associação, destacando que o ClassB também pode ser agregado por outras classs no aplicativo ( portanto, agregação também é conhecida como associação compartilhada).

insira a descrição da imagem aqui

É importante observar que o link de agregação não declara de qualquer forma que o ClassA possui ClassB nem que há um relacionamento pai-filho (quando pai é excluído como resultado de todos os seus filhos) entre os dois. Na verdade, muito pelo contrário! O link de agregação normalmente usado para enfatizar o ponto em que ClassA não é o contêiner exclusivo de ClassB, já que de fato o ClassB possui outro container.

Agregação vs Associação O link de associação pode replace o link de agregação em todas as situações, enquanto a agregação não pode replace a associação em situações onde há apenas um ‘elo fraco’ entre as classs, ou seja, ClassA tem método / s que contém parâmetro de ClassB mas ClassA não mantenha referência à instância ClassB.

Martin Fowler sugere que o link de agregação não deve ser usado porque não tem valor agregado e perturba a consistência, citando Jim Rumbaugh “Pense nisso como um placebo de modelagem”.

Composição (associação não compartilhada)

Devemos ser mais específicos e usar o link de composição nos casos em que além da parte de relacionamento entre ClassA e ClassB – há uma forte dependência de ciclo de vida entre os dois, significando que quando ClassA é excluído, o ClassB também é excluído como resultado

insira a descrição da imagem aqui

O link de composição mostra que uma class (contêiner, inteiro) tem propriedade exclusiva sobre outras classs / partes (s), significando que o object contêiner e suas partes constituem um relacionamento pai-filho / s.

Ao contrário da associação e agregação, ao usar o relacionamento de composição, a class composta não pode aparecer como um tipo de retorno ou tipo de parâmetro da class composta. Assim, as alterações na class composta não podem se propagar para o restante do sistema. Consequentemente, o uso da composição limita o crescimento da complexidade à medida que o sistema cresce.

Complexidade do sistema de medição

A complexidade do sistema pode ser medida simplesmente observando um diagrama de classs UML e avaliando as linhas de relacionamento de associação, agregação e composição. A maneira de medir a complexidade é determinar quantas classs podem ser afetadas pela mudança de uma determinada class. Se a class A expuser a class B, qualquer class que use class A pode, teoricamente, ser afetada por mudanças na class B. A sum do número de classs potencialmente afetadas para cada class no sistema é a complexidade total do sistema.

Você pode ler mais aqui: http://aviadezra.blogspot.com/2009/05/uml-association-aggregation-composition.html


Um relacionamento entre dois objects é referido como uma associação .

Uma associação é conhecida como composição quando um object possui outro.

Enquanto uma associação é conhecida como agregação quando um object usa outro object.

O problema com essas respostas é que elas são metade da história: elas explicam que a agregação e a composição são formas de associação, mas não dizem se é possível que uma associação não seja nenhuma delas.

Eu me reúno com base em algumas breves leituras de muitos posts sobre SO e alguns documentos da UML que existem 4 principais formas concretas de associação de class:

  1. composição: A é composta de um B; B não existe sem A, como um quarto em uma casa
  2. agregação: A has-a B; B pode existir sem A, como um estudante em sala de aula
  3. dependência: A usa um B; nenhuma dependência de ciclo de vida entre A e B, como um parâmetro de chamada de método, valor de retorno ou um temporário criado durante uma chamada de método
  4. generalização: A is-a B

Quando uma relação entre duas entidades não é uma delas, ela pode ser chamada de “uma associação” no sentido genérico do termo, e descreveu outras formas (nota, estereótipo etc.).

Meu palpite é que a “associação genérica” ​​se destina a ser usada principalmente em duas circunstâncias:

  • quando as especificidades de um relacionamento ainda estão sendo trabalhadas; Esse relacionamento em um diagrama deve ser convertido o mais rápido possível para o que realmente é / será (um dos outros 4).
  • quando um relacionamento não corresponde a nenhum desses 4 predeterminados por UML; a associação “genérica” ​​ainda dá a você uma maneira de representar um relacionamento que “não é um dos outros”, de modo que você não esteja preso usando um relacionamento incorreto com uma nota “isso não é realmente agregação, é apenas que UML não tem nenhum outro símbolo que possamos usar ”

Eu acho que esse link vai fazer sua lição de casa: http://ootips.org/uml-hasa.html

Para entender os termos, lembro-me de um exemplo nos meus primeiros dias de programação:

Se você tiver um object ‘tabuleiro de xadrez’ que contenha objects ‘box’ que seja composição, porque se o ‘tabuleiro de xadrez’ for excluído, não há mais motivos para as checkboxs existirem.

Se você tiver um object ‘quadrado’ que tenha um object ‘cor’ e o quadrado for excluído, o object ‘cor’ ainda pode existir, isto é, agregação

Ambos são associações , a principal diferença é conceitual

Composição : Este é o lugar onde uma vez que você destruir um object (escola), outro object (salas de aula) que é ligado a ele seria destruído também. Ambos não podem existir independentemente.

Agregação : Isso é exatamente o oposto da associação acima ( Composition ), em que uma vez que você mata um object ( Company ), o outro object ( Employees ) que está vinculado a ele pode existir por conta própria.

Associação .
Composição e Agregação são as duas formas de associação.

Composição (Se você remover “todo”, “parte” também será removido automaticamente – “Propriedade”)

  • Crie objects da sua class existente dentro da nova class. Isso é chamado de composição porque a nova class é composta de objects de classs existentes.

  • Normalmente, use variables ​​de membro normais.

  • Pode usar valores de ponteiro se a class de composição manipular automaticamente a alocação / desalocação responsável pela criação / destruição de subclasss.

insira a descrição da imagem aqui

Composição em C ++

 #include  using namespace std; /********************** Engine Class ******************/ class Engine { int nEngineNumber; public: Engine(int nEngineNo); ~Engine(void); }; Engine::Engine(int nEngineNo) { cout<<" Engine :: Constructor " < 

Saída

 --------------- Start Of Program -------------------- ------------- Inside Car Block ------------------ Engine :: Constructor Car :: Constructor Car :: Destructor Engine :: Destructor ------------- Out of Car Block ------------------ ------------- Inside Bus Block ------------------ Engine :: Constructor Bus :: Constructor Bus :: Destructor Engine :: Destructor ------------- Out of Bus Block ------------------ --------------- End Of Program -------------------- 

Agregação (Se você remover "whole", "Part" pode existir - "No Ownership")

  • Uma agregação é um tipo específico de composição em que não está implícita a propriedade entre o object complexo e os subobjects. Quando um agregado é destruído, os subobjects não são destruídos.

  • Normalmente, use variables ​​de ponteiro / variável de referência que apontam para um object que vive fora do escopo da class agregada

  • Pode usar valores de referência que apontam para um object que vive fora do escopo da class agregada

  • Não somos responsáveis ​​por criar / destruir subclasss

insira a descrição da imagem aqui

Código de agregação em C ++

 #include  #include  using namespace std; /********************** Teacher Class ******************/ class Teacher { private: string m_strName; public: Teacher(string strName); ~Teacher(void); string GetName(); }; Teacher::Teacher(string strName) : m_strName(strName) { cout<<" Teacher :: Constructor --- Teacher Name :: "< 

Saída

 --------------- Start Of Program -------------------- Teacher :: Constructor --- Teacher Name :: Reference Teacher Teacher :: Constructor --- Teacher Name :: Pointer Teacher ------------- Inside Block ------------------ Department :: Constructor Department :: Destructor ------------- Out of Block ------------------ Teacher :: Destructor --- Teacher Name :: Pointer Teacher Teacher :: Destructor --- Teacher Name :: Reference Teacher --------------- End Of Program -------------------- 

Eu gostaria de ilustrar como os três termos são implementados no Rails. O ActiveRecord chama qualquer tipo de relacionamento entre dois modelos de uma association . Não seria muito frequente encontrar os termos composition e aggregation , ao ler documentação ou artigos, relacionados ao ActiveRecord. Uma associação é criada adicionando uma das macros de class de associação ao corpo da class. Algumas dessas macros são belongs_to , has_one , has_many etc.

Se quisermos configurar uma composition ou aggregation , precisamos adicionar belongs_to ao modelo possuído (também chamado de child) e has_one ou has_many ao modelo proprietário (também chamado de pai). Se configurarmos composition ou aggregation dependeremos das opções que passamos para a chamada belongs_to no modelo filho. Antes do Rails 5, configurar belongs_to sem nenhuma opção criava uma aggregation , o filho poderia existir sem um pai. Se quiséssemos uma composition , precisávamos declarar isso explicitamente adicionando a opção required: true :

 class Room < ActiveRecord::Base belongs_to :house, required: true end 

No Rails 5 isso foi alterado. Agora, declarar uma associação belongs_to cria uma composition por padrão, o filho não pode existir sem um pai. Portanto, o exemplo acima pode ser reescrito como:

 class Room < ApplicationRecord belongs_to :house end 

Se quisermos permitir que o object filho exista sem um pai, precisamos declarar isso explicitamente por meio da opção optional

 class Product < ApplicationRecord belongs_to :category, optional: true end 
    Intereting Posts