Baixe o app para aproveitar ainda mais
Prévia do material em texto
1 4 DIAGRAMA DE CLASSES O diagrama de classes é um dos mais importantes e mais utilizados da UML. Seu principal enfoque está em permitir a visualização das classes que comporão o sistema com seus respectivos atributos e métodos, bem como em demonstrar como as classes do diagrama se relacionam, complementam e transmitem informações entre si. Esse diagrama apresenta uma visão estática de como as classes estão organizadas, preocupando-se em como definir a estrutura lógica das mesmas. O diagrama de classes serve ainda como base para a construção da maioria dos outros diagramas da linguagem UML. Basicamente, o diagrama de classes é composto por suas classes e pelas associações existentes entre elas, ou seja, os relacionamentos entre as classes. Alguns métodos de desenvolvimento de software, como o Processo Unificado, recomendam que se utilize o diagrama de classes ainda durante a fase de análise, produzindo-se um modelo conceituai a respeito das informações necessárias ao software. No modelo conceituai, o engenheiro preocupa-se apenas em representar as informações que o software necessitará, em termos de classes e seus atributos, bem como as associações entre as classes, não modelando características como os métodos que as classes poderão conter nessa etapa (os métodos já fazem parte do "como" o software será desenvolvido). Somente na fase de projeto toma-se o modelo conceituai do diagrama de classes e produz-se o modelo de domínio, que já enfoca a solução do problema. 4.1 ATRIBUTOS E MÉTODOS Classes costumam ter atributos que armazenam os dados dos objetos da classe, além de métodos, também chamados operações, que são as funções que uma instância da classe pode executar. Os valores dos atributos podem variar de uma instância para outra. Graças a essa característica, aliás, é possível identificar cada objeto individualmente, ao passo que os métodos são idênticos para todas as instâncias de uma classe específica. 2 Embora os métodos sejam declarados no diagrama de classes, identificando os possíveis parâmetros que são por eles recebidos e os possíveis valores por eles retornados, o diagrama de classes não se preocupa em definir as etapas que tais métodos deverão percorrer quando forem chamados, sendo esta uma função atribuída a outros diagramas, como o diagrama de atividade, que será analisado nos capítulos seguintes. A figura 1 apresenta um exemplo de classe contendo atributos e métodos. Figura 1 - Classe Uma classe, na linguagem UML, é representada como um retângulo com até três divisões, descritas a seguir: primeira contém a descrição ou nome da classe, que nesse exemplo é Conta_Comum. a segunda armazena os atributos e seus tipos de dados (o formato que os dados devem ter para serem armazenados em um atributo). No exemplo da figura 1 a classe Conta_Comum contém os atributos nro_conta, do tipo long; dt_abertura e dt_encerramento, do tipo Date (este não é um tipo primitivo e se refere a uma classe); situacao e senha, do tipo int; e saldo, do tipo double. a terceira divisão lista os métodos da classe. Nesse exemplo a classe ContcuComum contém os métodos abri r_Conta, cônsul 3 tar_Conta, vai idar_Senha, saldo_Conta, extrato_Conta, sacar_Valor, depositar_Valor e encerrar_Conta. Os símbolos de sustenido (#) e mais (+) na frente dos atributos e métodos representam a visibilidade dos mesmos, o que determina quais objetos de classes podem utilizar o atributo ou o método em questão. Não é realmente obrigatório que uma classe apresente as três divisões, pois pode haver classes que não tenham atributos ou que não contenham métodos, ou pode acontecer ainda que seus atributos e métodos não precisem ser apresentados no diagrama, já que é recomendado apresentar apenas atributos relevantes ao diagrama para evitar, por exemplo, tornar o diagrama muito poluído. Assim, é possível encontrar classes com somente duas divisões ou mesmo com apenas uma, no caso, aquela que contém a descrição da classe, porque esta é obrigatória. Métodos podem receber valores como parâmetros e retornar valores (da mesma forma que as funções implementadas na linguagem de programação C), que podem tanto ser o resultado produzido pela execução do método quanto simplesmente um valor representado se o método foi realizado com sucesso ou não. Nessa classe, por exemplo, podemos perceber que o retorno do método abrirConta é um long, que conterá o número da nova conta gerada. Por sua vez, o retorno dos métodos consultarConta, validarSenha, sacarValor, depositarValor e encerrarConta é um inteiro (int), e esse valor é utilizado para determinar se o método foi concluído com sucesso ou não. Por padrão o retorno 1 significa verdadeiro (ou sucesso) e 0 falso (ou fracasso). Já os métodos saldoConta e extratoConta retornam um double e uma String, que contêm o resultado da execução desses métodos. Para o método abrirConta, se o valor retornado for igual a 1 significará que o método foi concluído com sucesso e que uma nova conta foi aberta. Já se o retorno for igual a zero, saberemos que o método não foi concluído da forma esperada e que algum problema ocorreu. Na figura 1 os métodos foram apresentados sem o detalhamento de quais argumentos (parâmetros) eles deveriam receber (a lista de argumentos de um método, junto com seu valor de retorno, é chamada de assinatura da operação). Esse detalhamento é opcional, e isso foi feito propositadamente 4 para explicar os diagramas que serão apresentados no decorrer do capítulo. Alguns métodos podem ter muitos parâmetros, e o detalhamento destes em um diagrama que contenha muitas classes tornará esse diagrama muito extenso e será difícil visualizá-lo claramente como um todo, porque as classes ficarão largas. Assim, é melhor, quando se trata de apresentar um diagrama de classes composto por muitas classes, apresentar somente o nome dos métodos da classe, sem especificar os argumentos que ele receberá. O detalhamento dos métodos de cada classe poderá ser feito individualmente em um diagrama separado, conforme apresentado na figura 2. Figura 2 - Detalhamento das Assinaturas das Operações. Ao examinarmos a figura 2 podemos perceber que os métodos abrir_Conta e validar_Senha recebem um inteiro como parâmetro; o método consultar_Conta, um long; sacar_valor, um double; e depositar_valor, um long e um double. Já os outros métodos não recebem argumento algum. A partir do modelo da classe conta_Comum apresentada na figura 2 é possível gerar o código correspondente a ele. A seguir, será apresentado o código correspondente a essa classe implementado em Java1. public class Conta_Comum { 1 2 protected long nro_conta; 3 protected Date dt_abertura; 4 protected Date dt_encerrainento; 5 protected int situacao; 6 1 O autor não aplicou o padrão da linguagem Java, ou seja, escrita camelCase. 5 protected int senha; 7 protected double saldo; 8 9 public Conta_Comum(){ 10 } 11 public void finalize( ) throws Throwable { 12 } 13 14 public long abrir_Conta(int senha){ 15 return 0; 16 } 17 18 public int consultar_Conta(long nro_conta) { 19 return 0; 20 } 21 22 public int validarSenha (int senha) { 23 return 0; 24 } 25 26 public double saldoConta ( ) { 27 return 0; 28 } 29 30 public String extratoConta ( ) { 31 return ""; 32 } 33 34 public int sacarValor (double valor) { 35 return 0; 36 } 37 38public int depositarValor (long numeroConta, double valor) { 39 return 0; 40 } 41 42 public int encerrarConta ( ) { 43 return 0; 44 } 45 46 } 47 Obviamente esse código é apenas um esqueleto da classe. Como pode-se perceber, não há nenhum detalhamento de como os métodos irão desempenhar sua função. Além disso, será preciso criar uma classe chamada Date para que o compilador reconheça os atributos desse tipo. Observe que o valor de retorno em Java é declarado antes do nome do método, enquanto na UML ele é definido depois do nome do método e dos parâmetros que ele receberá. Os atributos de uma classe podem ainda ter características extras, entre as quais podemos citar valores iniciais, multiplicidade e se o atributo é 6 derivado, ou seja, se seus valores são produzidos por meio de algum tipo de cálculo, conforme apresentado na figura 3. Ao estudarmos esse exemplo podemos verificar que o valor inicial dos atributos situacao e saldo será respectivamente 1 e 0 quando da instanciação de um objeto dessa classe durante a abertura de uma nova conta. Dessa forma, sempre que uma nova conta for aberta sua situação inicial terá o valor 1 (está ativa), e o seu saldo permanecerá com valor 0 até que um depósito seja realizado. Pode-se perceber também que o atributo dataEncerramento, após a definição de seu tipo (Date), contém os valores [0..1]. Isso é chamado multiplicidade e, nesse contexto, significa que existirá no mínimo nenhuma (0) e no máximo uma (1) data de encerramento para a conta, uma vez que a conta pode estar aberta ainda e, portanto, não poderá ter uma data de encerramento e, se ela tiver sido encerrada, não poderá ter mais do que uma. Figura 3 - Detalhamento dos Atributos Os atributos dt_abertura, dt_encerramento e saldo têm uma barra (/) antes de seus nomes, significando que os valores desses atributos sofrem algum tipo de cálculo. No caso das datas, quando for realizada a operação de abertura de conta, o valor da data de abertura será tomado da data do sistema, o mesmo ocorrendo com o valor da data de encerramento quando do encerramento da conta. A rigor, não necessariamente isso poderia ser considerado um cálculo e sim uma simples atribuição, sendo que alguns poderiam considerar isso como sendo o valor inicial dos atributos. No entanto, principalmente no caso da data de encerramento, que será deixada indefinida 7 até que a conta seja encerrada, isso não seria verdadeiro, e o valor desse atributo seria definido em uma operação posterior à criação do objeto. Já no caso do saldo, ele precisa ser recalculado sempre que uma operação de saque ou depósito for realizada. 4.2 RELACIONAMENTOS OU ASSOCIAÇÕES As classes costumam ter relacionamentos entre si, chamados associações, que permitem que elas compartilhem informações entre si e colaborarem para a execução dos processos executados pelo sistema. Uma associação descreve um vínculo que ocorre normalmente entre os objetos de uma ou mais classes. As associações são representadas por linhas ligando as classes envolvidas. Essas linhas podem ter nomes ou títulos para auxiliar a compreensão do tipo de vínculo estabelecido entre os objetos das classes envolvidas nas associações. Há outras informações que uma associação poderá conter, conforme será visto ao longo do capítulo, na medida em que serão apresentadas as diversas formas de relacionamento possíveis em um diagrama de classes. 4.2.1 Associação Unária ou Reflexiva Este tipo de associação ocorre quando existe um relacionamento de um objeto de uma classe com objetos da mesma classe. Um exemplo de associação unária pode ser observado na figura 4. Figura 4 - Associação Unária. Ao examinarmos a figura 4, é possível perceber que a única classe do exemplo tem o nome Funcionário, e como atributo o nome do funcionário. 8 Observe que uma linha intitulada "chefia" parte da classe Funcionário e atinge a própria classe. Isso ocorre porque, nesse exemplo, um funcionário pode ser chefe de outros funcionários. O chefe de um funcionário também é, por sua vez, um funcionário da empresa e, portanto, também se constitui em uma instância da classe Funcionário. Logo, a associação denominada "chefia" indica uma possível relação entre uma ou mais instâncias da classe Funcionário com outras instâncias da própria classe Funcionário, ou seja, essa associação determina se um funcionário pode ou não chefiar outros funcionários. Observem que existe outra informação na associação, além de seu próprio nome, representada pelo valor "0..*" Essa informação é conhecida como multiplicidade. A multiplicidade procura determinar o número mínimo e máximo de objetos envolvidos em cada extremidade da associação, além de permitir especificar o nível de dependência de um objeto para com os outros envolvidos na associação. No caso apresentado na figura 3, a multiplicidade 0..* indica que um determinado funcionário pode chefiar nenhum (0) ou muitos (*) funcionários, ou seja, um funcionário pode não chefiar ninguém ou pode chefiar um ou mais funcionários. Pode-se perceber que só existe multiplicidade em uma das extremidades, por default, quando não existe multiplicidade explícita e entende- se que a multiplicidade é "1..1" significando que um e somente um objeto dessa extremidade da associação relaciona-se com os objetos da outra extremidade. Nesse exemplo, significa que um funcionário pode ou não chefiar outros funcionários, mas um funcionário tem um e apenas um funcionário como chefe imediato. A tabela 1 demonstra alguns dos diversos valores de multiplicidade que podem ser utilizados em uma associação. 9 Tabela 1 - Exemplos de multiplicidade Outra informação que pode, por vezes, ser considerada útil é a definição de papéis, que são informações extras na associação que podem ajudar a explicar a função de um objeto (o papel que este representa) dentro da associação. Um exemplo do uso de papéis pode ser visto na figura 5. Figura 5 - Associação Contendo Papéis. Nesse exemplo percebemos claramente qual a função de cada objeto envolvido na associação, sendo que o objeto na extremidade cuja multiplicidade é 1 executa o papel de chefe, enquanto os objetos na extremidade de multiplicidade muitos, interpretam o papel de subordinados. Como pode-se perceber, os papéis desse exemplo têm visibilidade pública, mas podem ter visibilidades protegidas ou privadas. O uso de papéis pode facilitar a compreensão da associação existente, mas nem sempre é necessário, e seu uso excessivo pode deixar os diagramas visualmente muito poluídos. 10 Na verdade, a classe Funcionário é uma classe persistente (embora não a tenhamos identificado explicitamente como tal), ou seja, suas instâncias deverão ser preservadas de alguma maneira em um banco de dados. No entanto, não é necessário definir atributos do tipo chave primária ou chave estrangeira, como no modelo entidade-relacionamento. Como regra geral, cada classe, ao ser declarada, já tem um código interno implícito, não sendo necessário declarar um atributo exclusivamente para isso. Ao final do capítulo trataremos da questão de persistência e mapeamento de classes em tabelas em bancos de dados relacionais. 4.2.2 Associação Binária Associações binárias ocorrem quando são identificados relacionamentos entre objetos de duas classes distintas. Esse tipo de associação é, em geral, a mais comumente encontrada. A figura 6 demonstra um exemplo de associação binária. Figura 6 - Associação Binária. Como podemos verificarna figura 6, um objeto da classe Socio pode relacionar-se ou não com instâncias da classe Dependente, conforme demonstra a multiplicidade 0..*, enquanto se existir um objeto da classe Dependente ele terá de se relacionar obrigatoriamente com um objeto da classe Socio, pois, como não foi definida a multiplicidade na extremidade da classe Socio, isto significa que esta é 1..1. Poderíamos acrescentar informações a essa associação, como definir a navegabilidade da mesma, conforme demonstrado na figura 7. A navegabilidade é representada por uma seta em uma das extremidades da associação, identificando o sentido em que as informações são transmitidas entre os objetos das classes envolvidas, ou seja, o sentido em que os métodos poderão ser disparados. Nesse exemplo, um objeto da classe 11 Socio o poderá disparar métodos em objetos da classe Dependente, mas a recíproca não é verdadeira: um objeto da classe Dependente não poderá disparar métodos em um objeto da classe Socio. A navegabilidade não é obrigatória, mesmo porque, se não houver setas, significa que as informações podem trafegar entre os objetos de todas as classes da associação. Figura 7 - Associação binária com Navegabilidade A navegabilidade é uma informação que só deve ser acrescentada na fase de projeto, porém é possível durante a fase de análise definir a direção de leitura da associação, representada, em algumas ferramentas CASE, como um triângulo em forma de seta ao lado do nome da associação, em outras ferramentas, porém, não há diferenciação entre a seta de direção de leitura e a de navegabilidade. A direção de leitura e a navegabilidade não são exatamente a mesma coisa, o sentido de leitura tem como objetivo somente facilitar a compreensão da associação, enquanto a navegabilidade define em que sentido os métodos poderão ser disparados. No exemplo da figura 6, o uso da direção de leitura nos transmitiria a informação de que a leitura da associação deveria ser feita da seguinte forma: "Uma instância da classe Soei o possui, no mínimo, nenhuma instância e no máximo, muitas instâncias da classe Dependente e uma instância da classe Dependente é possuída por uma e somente uma instância da classe Socio". 4.2.3 Associação Ternária ou N-ária Associações ternárias ou n-árias são associações que conectam objetos de mais de duas classes. São representadas por um losango para onde convergem todas as ligações da associação. Afigura 8 apresenta um exemplo de associação ternária. Nessa ilustração identificamos uma associação que demonstra um fato corriqueiro na maioria das universidades, em que um professor pode lecionar 12 para muitas turmas, uma turma pode ter muitos professores e utilizar muitas salas de aula e um professor, ao lecionar para uma turma específica, pode utilizar mais de uma sala de aula (ele pode ministrar aulas teóricas em salas comuns ou práticas em laboratório). Assim, podemos ler a associação apresentada na figura 8 da seguinte forma: "Um professor leciona para no mínimo uma turma e no máximo para muitas, uma turma tem no mínimo um professor e no máximo muitos, e um professor, ao lecionar para uma determinada turma, utiliza no mínimo uma sala de aula e no máximo muitas". As associações ternárias são úteis para demonstrar associações complexas. No entanto, deve-se evitar utilizá-las, pois sua leitura é, por vezes, difícil de ser interpretada. Figura 8 - Associação Ternária 13 Questões 1. Quais são os objetivos do Diagrama de Classes? 2. Qual a visão do Diagrama de Classes? 3. Defina orientação a objetos? 4. Defina classe? 5. O que são atributos? 6. Defina métodos? 7. Defina herança? 8. Como é representada uma classe no diagrama? 9. O que são relacionamentos ou associações? 10. Como são representadas as associações?
Compartilhar