Baixe o app para aproveitar ainda mais
Prévia do material em texto
Outros relacionamentos entre classes Os relacionamentos representam os mais relevantes elementos de um diagrama de classes. Estudaremos os relacionamentos mais usados na modelagem de classes. Além das associações, são possíveis os seguintes relacionamentos: Classe de associacão; Generalizacão/ especializacão (herança); Agregação; Composição; Dependência. Classes de associação A figura a seguir ilustra o relacionamento entre classes chamado de classe de associação. É uma classe que surge do relacionamento de associação entre outras duas classes. Imagine que um leitor (classe) de uma biblioteca solicita o empréstimo de um exemplar de livro (classe). Nesse momento, surge a necessidade de armazenar alguns atributos como: data de empréstimo e data de data de devolução, além de métodos para registrar o empréstimo, registrar a devolução e tratar a multa em caso de atraso na devolução. Tais atributos e métodos não podem ser associados à classe leitor nem tampouco à classe exemplar de livro. Não seria adequado incluir tais atributos e métodos em nenhuma dessas classes, pois não dizem respeito a elas. Surge então uma nova classe, denominada de empréstimo, como consequência da associação entre leitor e exemplar de livro, que deverá armazenar todos os atributos e métodos derivados dessa asssociacão. O relacionamento classe de associação é representado por reta pontilhada, a partir de uma associação entre duas classes, conforme podemos ver nesta figura: Generalização/ especialização A generalização/ especialização é o relacionamento entre classes que implementa o conceito de herança, com reaproveitamento de código, preconizado pela orientação a objetos. Uma classe mais geral se relaciona com outra mais específica (herdada). A classe mais específica herda todas as características (atributos e métodos) permitidos da classe mais geral. A classe mais geral também é chamada de superclasse, e a classe mais específica chama-se subclasse. A imagem a seguir ilusta o relacionamento de generalização/ especialização, em um exemplo típico, envolvendo clientes pessoas físicas e jurídicas, que tem diferenças mas também semelhanças. As semelhanças podem ser agrupadas na classe mais geral, cliente (a superclasse), e as diferenças ficam nas subclasses, pessoa física e pessoa jurídica. O relacionamento de generalização/ especializacão é representado por uma reta com uma seta sem preenchimento na ponta, apontando para a classe mais geral. A leitura é: “A pessoa física é um cliente; A pessoa jurídica é um cliente”. O relacionamento de generalização/ especialização contém algumas especificidaes, chamadas de restrições, que acrescentam informações mais precisas sobre como a generalização deve ser usada e estendida no futuro. - Generalização completa e incompleta Uma restrição indicando que a generalização é completa significa que todas as subclasses (especializações) já foram especificadas e não existe mais a possibilidade de outra generalização no futuro. A incompleta é o contrário, e é o padrão da UML. O exemplo a seguir ilustra o uso dessa restrição completa, na qual uma pessoa é homem ou mulher, não havendo novas subclasses possíveis para a superclasse pessoa. A figura a seguir mostra o principio da herança chamado transitividade: A classe Cl2 herda o atributo Cl1 (visibilidade protegida); A classe Cl3 herda o atributo M2 de Cl2; A classe Cl3 herda o atributo M1 de Cl1, pelo princípio da transitividade. Agregação e composição Uma das maiores fontes de confusão e dúvidas na modelagem de classes é o uso dos relacionamentos de agregação e composicão. Esses dois relacionamentos são do tipo “todo-parte”, ou seja, existe uma classe que denota um todo e outras que denotam as partes. A grande dificuldade está em diferenciar agregação de composição. A composição é um relacionamento mais forte, no qual podemos prever as seguintes características: Embora uma classe possa ser um componente de muitas outras classes, toda instância deve ser componente de apenas um proprietário, o que significa dizer que teremos a cardinalidade 1 do lado do objeto “todo” (proprietário). Em outras palavras, os objetos “parte” somente podem pertencer a um único objeto “todo”; Se o todo for excluído, todas as partes devem ser também, ou seja, quando o todo “morre”, todas as partes também “morrem”. A vida do todo e das partes são coincidentes. Quando num relacionamento “todo-parte” as duas propriedades citadas não forem identificadas, estamos diante de uma agregação. Ou seja, a constatação de que o relacionamento é uma agregação deriva da análise das duas características citadas e da conclusão de que não é uma composição. A representação da agregação é por um losango (que muitos chamam de diamante) sem preenchimento, do lado do objeto “todo”. A representação da composição é pelo mesmo elemento, porém colorido de preto, também do lado do objeto “todo”. As figuras a seguir ilustram cada um dos relacionamentos. A primeira mostra um relacionamento de agregação entre as classes prova e questões. A segunda mostra um relacionamento de composição entre as classes pedido e itens de pedido. Vamos analisar cada um dos dois relacionamentos a seguir, à luz das duas características descritas e explicar o porquê de serem agregação e composição, respectivamente. - Por que o relacionamento entre prova e questões é uma agregação? Analisando o relacionamento ilustrado na figura a seguir, sob a luz das duas características descritas, temos: O objeto “parte” questões pode pertencer a mais de um todo, uma vez que uma questão pode ser parte integrande de mais de uma (várias) provas; Quando uma prova deixa de existir, as questões nela contidas podem (e devem) continuar existindo, para que possam ser usadas em outras provas; logo, a vida das partes não é coincidente com a vida do todo. Concluindo: como nenhuma das propriedades foi analisada como verdadeira, podemos concluir que o relacionamento entre prova e questões não se trata de composição. Como é um relacionamento “todo-parte”, concluimos tratar-se de uma agregação. - Por que o relacionamento entre pedido e itens pedido é uma composição? Analisando o relacionamento ilustrado na figura a seguir, sob a luz das duas características descritas, temos: O objeto “parte” itens pedido não pode pertencer a mais de um todo, pois aquele item é daquele pedido e não poderá estar em outro; Quando um pedido deixa de existir, não faz sentido os seus itens permanecerem ativos, “vivos”; logo, quando o pedido (todo) “morre”, os itens pedido (parte) também “morrem”. Concluindo: como as duas características foram analisadas como verdadeiras, podemos concluir que o relacionamento entre pedido e itens pedido é uma composição. Embora as duas características ajudem muito a elucidar a dúvida sobre qual dos dois relacionamentos é mais apropriado, devemos sempre analisar o contexto, para entender como se relacionam todo e parte. Por fim, afirmamos que a composição é um relacionamento que diz muita coisa a quem vai implementar as classes, na linguagem de programação, pois orienta que a criação e destruição das partes está condicionada à vida do todo. Já a agregação não tem essa particularidade. Uma agregacão poderá, se desejado, sersubstituída por uma associação simples, já que não tem grandes valores semânticos, a não explicitar que se trata de uma relação “todo-parte”. Dependência A dependência entre duas classes existe se: mudanças na definição de uma classe puder demandar mudanças na definição da outra classe. As dependências podem ser evidenciadas de várias formas, como por exemplo: Uma classe tem outra como parte de seus dados; Uma classe menciona outra como parâmetro de uma chamada de método. Se a interface da classe dominante muda, as mensagens enviadas podem não ser mais válidas, demandando alterações na classe dependente. Sabemos o quanto esse tipo de alteração provoca problemas endêmicos em sistemas, acarretando o chamado “efeito em cascata”, ou seja, uma alteração em parte do código resulta como consequência (erros, problemas) em outras partes. Na modelagem UML, veremos muitas dependências, mas você deve ser seletivo e modelar dependências apenas quando ela for relevante para o contexto específico de sua aplicação. Um dos usos mais comuns da dependência é na modelagem de um relacionamento transitório, como quando um objeto é passado para outro como parâmetro. A imagem a seguir ilustra um relacionamento de dependência entre as classes estudante e disciplina. A dependência é representada por uma seta pontilhada, que sai da classe dependente. Ou seja, no relacionamento a seguir, disciplina depende (é dependente) de estudante. Observe o método incluir da classe disciplina. Ela usa como parâmetro o objeto aluno, que é da classe estudante. Isto significa que qualquer mudança na interface (assinatura) de estudante poderá afetar a classe disciplina.
Compartilhar