Para que serve Associação, Agregação e Composição?

20

Eu já passei por muitas teorias sobre o que é encapsulamento e as três técnicas para implementá-lo, que são Associação, Agregação e Composição.

O que eu encontrei é :

Encapsulamento

Encapsulamento é a técnica de tornar os campos em uma classe privados e fornecer acesso aos campos por meio de métodos públicos. Se um campo for declarado privado, ele não poderá ser acessado por ninguém fora da classe, ocultando assim os campos da classe. Por esse motivo, o encapsulamento também é conhecido como ocultação de dados.

O encapsulamento pode ser descrito como uma barreira protetora que impede que o código e os dados sejam acessados ​​aleatoriamente por outro código definido fora da classe. O acesso aos dados e código é fortemente controlado por uma interface.

O principal benefício do encapsulamento é a capacidade de modificar nosso código implementado sem quebrar o código de outras pessoas que usam nosso código. Com esse recurso, o encapsulamento fornece manutenção, flexibilidade e extensibilidade ao nosso código.

Associação

Associação é um relacionamento em que todos os objetos 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 objetos e ambos têm seu próprio ciclo de vida. Ambos podem criar e excluir independentemente.

Agregação

A agregação é uma forma especializada de associação, na qual todos os objetos têm seu próprio ciclo de vida, mas existe propriedade e um objeto filho não pode pertencer a outro objeto 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 objeto do professor não será destruído. Podemos pensar nisso como um relacionamento “tem um”.

Composição

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 objeto filho não possui seu ciclo de vida e se o objeto pai excluir todos os objetos filhos também serão excluídos. Vamos retomar um exemplo de relação entre casa e quartos. A casa pode conter vários quartos, mas não há vida independente de um quarto e nenhum quarto pode pertencer a duas casas diferentes. Se excluirmos a casa, a sala será excluída automaticamente.

A questão é:

Agora, todos esses são exemplos do mundo real. Estou procurando uma descrição sobre como usar essas técnicas no código de classe real. Quero dizer qual é o objetivo de usar três técnicas diferentes de encapsulamento , como essas técnicas podem ser implementadas e como escolher qual técnica é aplicável no momento.

Sahil Mahajan Mj
fonte
1
Observe que agregação, composição e associação não são técnicas para implementar o encapsulamento. Um encapsulamento também pode existir mesmo se houver apenas uma classe / objeto. O encapsulamento é apenas um recurso essencial na Orientação a objetos para ocultar os dados do seu objeto.
Maxood
1
"Um único professor NÃO pode pertencer a vários departamentos", sério? Você não notou que seu recurso modificou o conteúdo?
KNU 12/02
Consegui usar o Composition para identificar as raízes agregadas DDD e suas entidades ao criar um design orientado a domínio. Um novo uso para uma convenção antiga.
Jonn

Respostas:

12

A distinção entre associação, agregação e composição, como você a descreve, é um legado que remonta aos velhos tempos do gerenciamento manual de memória. Por exemplo, em C ++, a memória usada pelos objetos deve ser liberada manualmente e, portanto, é fundamental projetar cuidadosamente o ciclo de vida dos objetos compostos. Embora a distinção entre agregação e composição ainda esteja sendo ensinada por muitos livros de texto, ela é essencialmente irrelevante na programação em ambientes com gerenciamento automático de memória. Se você tem coleta de lixo, todos são apenas composição, ponto final.

O encapsulamento, por outro lado, é um princípio muito mais geral do que o que você descreve. É a principal idéia de agrupar dados e as funções que operam nesses dados em um módulo. Uma maneira de implementar isso é manter o estado do módulo privado e expor as alterações nesse estado por meio de serviços públicos. Portanto, o cliente não pode acessar o estado por conta própria, mas precisa informar ao módulo sua intenção enviando mensagens. Portanto, o encapsulamento não se limita aos objetos, mas também aos serviços. Na verdade, uma maneira de ver objetos é vê-los como serviços.

Aqui está um exemplo de encapsulamento

public class Counter {
    private int n = 0;
    public int inc() { return n++; }
}

ou o mesmo usando funções lambda

var counter = (function() {
    var n = 0;
    var inc = function() { return n++; }
    return inc;
})();

Nos dois casos, os dados, que são a variável n, são agrupados com a função incque opera nele. E não há como qualquer outra função acessar n, portanto, temos um módulo encapsulado que fornece a contagem como um serviço.

Nota: expor todo o estado interno de um objeto através de acessadores é na verdade uma violação do encapsulamento. Infelizmente, é uma violação tão comum que muitos a confundem com um bom design orientado a objetos.

akuhn
fonte
2
O Gerenciamento automático de memória não tem nada a ver com relacionamentos de objetos. O próprio diagrama de objetos informa ao programador como codificar as classes, suas interfaces e métodos, conforme os requisitos do sistema em consideração.
Maxood
2
Há também uma consideração fora da memória. No design de dados ou talvez serialização. Na composição, pode ser necessário ter diferentes restrições de chave estrangeira em um RDBMS ou, possivelmente, alterar a maneira como você lida com a serialização de um objeto se ele tiver filhos compostos versus filhos agregados ou filhos agregados ou objetos associados.
Chris
8

Encapsulamento é a técnica de tornar os campos em uma classe privados e fornecer acesso aos campos por meio de métodos públicos. Se um campo for declarado privado, ele não poderá ser acessado por ninguém fora da classe, ocultando assim os campos da classe. Por esse motivo, o encapsulamento também é conhecido como ocultação de dados.

    public class Test{

    private String name;

       private int age;

       public int getAge(){
          return age;
       }

       public String getName(){
          return name;
       }
    }

Consulte esta pergunta também .

Associação indica o relacionamento entre objetos. Por exemplo: o computador usa o teclado como dispositivo de entrada.

Uma associação é usada quando um objeto deseja que outro objeto execute um serviço para ele.

A agregação é um caso especial de associação. Uma associação direcional entre objetos. Quando um objeto 'tem' um 'outro objeto, você tem uma agregação entre eles.

por exemplo: Sala tem uma mesa, mas a mesa pode existir sem a sala.

    class Room {

      private Table table;

      void setTable(Table table) {
        this.table = table;
      }

    }

A composição é um caso especial de agregação. A composição é mais restritiva. Quando há uma composição entre dois objetos, o objeto composto não pode existir sem o outro objeto. Essa restrição não existe na agregação. por exemplo: quartos em uma casa, que não podem existir após a vida útil da casa.

    class House {

      private  Room room;

      House(Room roomSpecs) {
        room = new Room(roomSpecs);
      }

    }

Composition é uma técnica de design para implementar um relacionamento has-a nas classes, por Herança ou Composição do objeto para reutilização de código.

Uma das melhores práticas em programação Java é usar composição sobre herança

Kapil das
fonte
Como isso responde à pergunta?
Gnat #
1

O uso dessas técnicas geralmente resulta em práticas de design como o SOLID ou em vários padrões de design .

O objetivo de usar padrões, práticas e outras coisas é descrever uma solução para um problema específico que também é sustentável e extensível. Você simplesmente precisa ter experiência suficiente para dizer onde usar qual padrão ou técnica.

Eufórico
fonte
1

Sinceramente, sinto que essas noções ensinadas na academia têm sua importância nos contextos de orientação a objetos e design de classe. Esses conceitos nos ajudam muito quando se trata de modelar um sistema a partir do zero. Associação, Agregação e Composição pertencem exclusivamente ao diagrama de classes da UML e são completamente independentes de restrições de tecnologia, como problemas de memória.

Além disso, você também deve considerar o nível mais alto ou as metas de negócios do sistema que está modelando. Temos objetos como House e Room em nosso sistema em consideração, mas não podem ser fortemente relacionados (via composição). Por exemplo, se estou modelando um sistema imobiliário, talvez precise saber qual cômodo pertence a que casa. Mas vamos modelar um sistema de pesquisa ou censo em que quero saber quantas pessoas estão morando em cada cômodo da casa em uma determinada área, então simplesmente não preciso relacionar um cômodo com uma casa por meio de composição.

Outro exemplo poderia ser de um pomar e certo tipo de fruta. Digamos que só posso considerar um pomar quando tenho macieiras plantadas dentro dele. O ponto principal é que os requisitos do sistema geral são muito importantes.

O encapsulamento é um dos pilares do Design Orientado a Objetos. Você precisa agrupar seus dados e as operações que você executará em seus dados. você também precisa ocultar certos atributos do seu objeto do mundo exterior para permitir que esse objeto sobreviva em um estado válido. Quando dois objetos estão interagindo, eles precisam interagir entre si por meio de uma interface. E é isso que o encapsulamento garante quando projetamos nosso sistema OO.

Aqui está como esses conceitos são aplicados ao código:

ASSOCIAÇÃO: Associação indica o relacionamento entre objetos. Ele permite que o programador saiba quais métodos escrever em suas classes para fazê-los interagir entre si. Você pode encontrar vários exemplos de diagramas de código e classe para entender a associação. No seu exemplo de Teach and Student, existe uma relação de ensino e ensinado por . Então, você simplesmente escreverá um conjunto de métodos (tecnicamente chamados de interface), através dos quais poderá conhecer qual aluno tem quais professores e qual professor tem que alunos. A associação também permite que o modelador do sistema ajude o designer do banco de dados sobre os atributos e campos que precisam ser mantidos no banco de dados.

COMPOSIÇÃO: Se um objeto é parte integrante de outro objeto, talvez seja necessário indicar esse relacionamento no construtor do outro objeto. Por exemplo, no seu cenário de Casas e quartos, podemos escrever o código a seguir, caso desejemos saber qual quarto pertence a que tipo de casa.

class House{
          string _HouseType;   
     public:    
    void setHouseType(string house_type)
     {
        this. _HouseType = house_type;
     } 

     string getHouseType()
    {
       return _HouseType;
    }
};



 House HouseObject = new House();


class Room{

 public: 
 Room(string HouseType) {
       this._HouseType = HouseObject.getHouseType();  //as in my system a room cannot exist without a house

 } 

};

O programador também garantirá, ao invocar destruidores do objeto, que o destruidor do outro objeto também seja invocado. Isto é crucial.

AGREGAÇÃO: Digamos que, se o relacionamento entre os objetos for fraco, então, para o programador, isso significaria usar uma variável de instância para indicar o relacionamento. E, em seguida, escreva um functon mutador (setter) para fornecer valor a esse objeto de outro.

class Department{

 string dept_name;

public:
   void setDeptName(string name)
   {
        this.dept_name=name;
   }

   string getDeptName()
   {
        return dept_name; 
   }

};



 Department DepartmentObject = new Department();

class Teacher{

 string dept_name;

public:

  setDeptName(string name)
  {
     this.dept_name = DepartmentObject.getDeptName();  //You only need to invoje this method when needed (aggregation)
  }
}

};
Maxood
fonte
1

OK, vamos mapear isso para algumas propriedades principais, em vez de conceitos abstratos, que só fazem sentido quando você entender o que elas significam. Como alguns comentaristas, não concordo com a resposta aceita, digo que esses são conceitos independentes do gerenciamento de memória.

Encapsulamento

Você deseja ocultar a complexidade do cliente, publicando apenas o que importa do ponto de vista do cliente, facilitando as coisas para o cliente. Como bônus, você tem a certeza de que nada pode mexer com o código encapsulado. Desde que você respeite a interface e a funcionalidade, poderá refazer as coisas e ter certeza de que não quebrará nada. A dependência está apenas na interface publicada.

O encapsulamento é um dos principais pilares da orientação a objetos. Não é um padrão, é um princípio e pode ser aplicado à lógica e aos dados. É apenas um benefício básico do uso de classes, não algo que você veria explicitamente declarado em um diagrama ou documento de design.

Associação

Este é um conceito muito flexível que basicamente descreve apenas uma dependência entre objetos. Um objeto conhece a existência de outro objeto e pode usar sua funcionalidade em algum momento. Em um diagrama, a associação alertaria você de que existe uma dependência e que a alteração de um objeto pode afetar o outro. Não é uma técnica a ser aplicada quando você tem algum problema a resolver, é mais um fato da vida que você deve estar ciente de quando ele está lá. É um relacionamento. Como uma fatura com uma propriedade Pedidos. O pedido e a fatura têm seu próprio ciclo de vida. Um é sobre bens e o outro é sobre pagamento, o que os torna essencialmente independentes, mas é importante saber por quais bens estão sendo pagos.

Contenção

Estou adicionando isso porque ele pertence à série e tornará a agregação mais significativa. Não ouço muito o termo sendo usado em um contexto SE, mas acho que ainda é útil. A contenção implica encapsulamento, mas é estritamente sobre instâncias de objetos particulares à classe que os contém. A funcionalidade dos objetos contidos é exposta seletivamente por meio de interfaces públicas. A classe que contém controla o ciclo de vida dos objetos controlados. Você usa isso quando precisa de alguns recursos de uma classe existente para tornar funcional a classe que o contém. Pode ser um analisador XML e o cliente da classe que contém pode nunca ver ou saber nada relacionado a XML. Como uma metáfora, pense no objeto contido como um funcionário administrativo. Os clientes nunca conhecem essas pessoas, mas são necessários para prestar o serviço.

Agregação

É muito parecido com a contenção, exceto pelo controle do ciclo de vida e pela visibilidade dos objetos agregados. Os objetos agregados já estão disponíveis em um contexto diferente e são gerenciados por uma entidade diferente. O agregador está apenas oferecendo uma fachada, um portal para os objetos agregados. Quando o cliente endereça o agregado, ele obtém a interface do próprio objeto agregado, não um invólucro ao seu redor. O objetivo do agregado é oferecer um agrupamento lógico de coisas. Pense em um ponto de acesso a serviços ou algum outro objeto wrapper.

Composição

Parece-me que este é o termo mais contemporâneo para contenção, possivelmente porque foi cunhado em um livro popular de origem relativamente recente. Onde a contenção se concentra nos aspectos técnicos das relações com os objetos, a composição é normalmente usada no contexto das decisões de design, mais especificamente como uma alternativa mais flexível para a herança.

Ele não diz muito sobre a natureza dos relacionamentos ou propriedade dos objetos, apenas indica que a funcionalidade é implementada combinando a funcionalidade das classes existentes. Portanto, eu argumentaria que não pertence a esta série, porque não diz nada sobre os aspectos técnicos de uma implementação onde os outros fazem.

Martin Maat
fonte