Implementando UML em java
Veremos como a UML pode ser interpretada, implementando algumas das características do sistema em relação a utilização dos relacionamentos.
A UML Unified Modeling Language foi desenvolvida por Grady Booch, James Rumbaugh, e Ivar Jacobson que são conhecidos como "os três amigos". Eles possuem um extenso conhecimento na área de modelagem orientada a objetos já que as três mais conceituadas metodologias de modelagem orientada a objetos foram desenvolvidas por eles e a UML é a junção do que havia de melhor nestas três metodologias adicionando novos conceitos e visões da linguagem.
Veremos como a UML pode ser interpretada, implementando algumas das características do sistema em relação a utilização dos relacionamentos.
As Classes
Uma classe é a descrição de um tipo de objeto. Todos os objetos são instâncias de classes, onde a classe descreve as propriedades e comportamentos daquele objeto. Objetos só podem ser instanciados de classes. Usamos classes para classificar os objetos que identificamos no mundo real.
Identificar as classes de um sistema pode ser complicado, e deve ser feito por experts no domínio do problema a que o software modelado se baseia. As classes devem ser retiradas do domínio do problema e serem nomeadas pelo que elas representam no sistema.
A sintaxe usada é independente de qualquer linguagem de programação.
Relacionamentos
Os relacionamentos ligam as classes/objetos entre si criando relações lógicas entre estas entidades. Os relacionamentos podem ser de:
Associação: É uma conexão entre classes, e também significa que é uma conexão entre objetos daquelas classes. Uma associação representa que duas classes possuem uma ligação (link), por exemplo, elas "conhecem uma a outra", "estão conectadas com", "para cada X existe um Y" e assim por diante. Classes e associações são muito poderosas quando modeladas em sistemas complexos.
É possível conectar uma classe a ela mesma através de uma associação e que ainda representa semanticamente a conexão entre dois objetos, mas os objetos conectados são da mesma classe. Uma associação deste tipo é chamada de associação recursiva.
public class PedidoItem
{
public Pedido thePedido;
public Pedido pedidoQualificado;
public PedidoItem()
{
}
}
public class Cliente
{
public Cliente()
{
}
}
public class Pedido
{
public PedidoItem pedidoItemQualificado;
public PedidoItem thePedidoItem[];
private Cliente cliente;
public Pedido()
{
}
}
Agregação: É uma forma especial de associação utilizada para mostrar que um tipo de objeto é composto, pelo menos em parte, de outro em uma relação todo/parte. Indicando que o objeto parte "é um atributo" do objeto todo, onde o ciclo de vida do objeto parte é limitado ao ciclo de vida do objeto todo. A agregação é um caso particular da associação. A agregação indica que uma das classes do relacionamento é uma parte, ou está contida em outra classe. As palavras chaves usadas para identificar uma agregação são: "consiste em", "contém", "é parte de".
public class Produto
{
private PedidoItem pedidoItem;
public Produto() { }
}
public class Pedido
{
private PedidoItem pedidoItem[];
public Pedido()
{
}
}
public class PedidoItem
{
private Pedido pedido;
private Produto produto;
public Produto theProduto;
public PedidoItem()
{
}
}
Generalização: É um relacionamento de um elemento mais geral e outro mais específico. O elemento mais específico pode conter informações adicionais.
A generalização é um relacionamento entre um elemento geral e um outro mais específico. O elemento mais específico possui todas as características do elemento geral e contém ainda mais particularidades. Um objeto mais específico pode ser usado como uma instância do elemento mais geral. A generalização, também chamada de herança, permite a criação de elementos especializados em outros.
public class Marca {
private int descrição;
private int logotipo;
public Marca() {}
}
public abstract class Veículo {
private String chassi;
private String placa;
private String modelo;
private String cor;
protected Marca marca;
public Veículo() {}
}
public class VeículoDePasseio extends Veículo {
private int quantidadeDePassageiros;
public VeículoDePasseio() {}
}
public class VeiculoDeCarga extends Veiculo {
private int cargaMáxima;
public VeículoDeCarga() {}
}
Herança em Java
No topo da hierarquia em Java está a classe Object. Esta é a classe mais geral da hierarquia e todas as outras descendem dela. Por definição, em Java, cada nova classe que não especifica sua superclasse é considerada, por default, como subclasse de Object. Java permite a sobreposição de métodos com a mesma assinatura. Ou seja, se uma classe desejar implementar de modo diferente um determinado método, pode citálo outra vez na definição da classe acompanhado do respectivo código, que passa então a prevalecer para esta classe e suas possíveis herdeiras.
Java implementa a herança simples: cada classe pode ter apenas uma superclasse. Em outras linguagens orientadas por objeto, como C++, as classes podem ter mais de uma superclasse, herdando assim métodos e variáveis combinados de várias classes. Isto é chamado de herança múltipla. Embora este tipo de herança aumente muito o poder de programação, dificulta muito também a implementação da linguagem. Java não implementa herança múltipla.
public class Periferico {
public Periferico() {
}
private String tipo;
public void setTipo(String tip) {
tipo = tip;
if (tipo.equals("E")) {
tipo = "ENTRADA";
} else if (tipo.equals("S")) {
tipo = "SAÍDA";
} else if (tipo.equals("A")) {
tipo = "ENTRADA/SAÍDA";
} else {
System.out.print("Opção Não corresponde!. Repita a Operação");
tipo = "repita";
}
}
public String getTipo() {
return tipo;
}
}
public class Monitor extends Periferico {
public Monitor() {
this.tipo = "S";
}
private String marca;
private String serie;
public void setMarca(String mar) {
marca = mar;
}
public String getMarca() {
return marca;
}
public void setSerie(String ser) {
serie = ser;
}
public String getSerie() {
return serie;
}
}
Interfaces, uma alternativa para a Herança Múltipla
Herança múltipla é a capacidade de uma classe herdar de duas ou mais classes, por exemplo a classe radio-relógio herdar da classe rádio e da classe relógio. Um dos problemas que podem surgir é o conflito de nomes de atributos ou métodos herdados desse tipo de herança. Uma das estratégias adotadas para resolver estes conflitos é o "renaming" ou renomeamento desses nomes iguais presentes nas superclasses. Tendo o seguinte significado:
A classe herdeira tem comportamento, "behaviour", semelhante ao das duas classes pais. Um outro exemplo seria a classe audio-vídeo que herda da classe audio e da classe vídeo. Java por motivos de simplicidade, abandona a idéia de herança múltipla, cedendo lugar ao uso de interfaces. Interfaces são um conjunto de métodos e constantes (não contém atributos). Os métodos definidos na interface são desprovidos de implementação. Classes podem dizer que implementam uma interface, estabelecendo um compromisso, uma espécie de contrato, com seus clientes no que se refere a prover uma implementação para cada método da referida interface.. Ao cliente, pode ser dada a definição da interface, ele acaba não sabendo o que a classe é, mas sabe o que faz.
public interface Imprimivel {
final char nlin ='\n'; //nova linha
public String toString();
//assinatura de método para impressão na tela
public void toSystemOut();
}
public class Produto implements Imprimivel {
//um produto comercial qualquer
protected String descricao;
protected int quantidade;
public Produto(String d,int q) {
descricao=d;
quantidade=q;
}
public String toString() {
return new String(" "+descricao+" "+quantidade);
}
//método para impressão na tela
public void toSystemOut() {
System.out.print(descricao + quantidade);
}
}
Uma interface poderia estender a interface Imprimivel e ter mais assinaturas para a sua implementação.
interface Imprimivel2 extends Imprimivel {
//assinatura de método para impressão Formatada na tela
public void toSystemOutFormated();
}
public class Teclado extends Periferico implements Imprimivel2 {
public Teclado() {
this.tipo = "E";
}
private String tipoEntrada;
private String idioma;
public void setTipoEntrada(String tipo) {
tipoEntrada = tipo;
}
public String getTipoEntrada() {
return tipoEntrada;
}
public void setIdioma(String idi) {
idioma = idi;
}
public String getIdioma() {
return idioma;
}
public String toString() {
return new String(" "+descricao+" "+quantidade);
}
//método para impressão na tela
public void toSystemOut() {
System.out.print(descricao + quantidade);
}
//método para impressão Formatada na tela
public void toSystemOutFormated() {
System.out.print("Descrição: " + descricao + nlin
+ "Quantidade: " + quantidade);
}
}
Conclusão
A criação de uma linguagem para a comunidade de desenvolvedores em orientação a objetos era uma necessidade antiga. A UML realmente incorporou muitos recursos que dão à linguagem uma extensibilidade muito grande, porém o que ainda preocupa e muito é a incorreta utilização dos conceitos na hora da implementação.
- ERIKSSON, Hans-Erik & PENKER, Magnus. UML Toolkit. Editora Wiley, 1998.
- PRESSMAN, Roger. Engenharia de Software.3ª ed. Editora McGrawHill, 1995.
- COAD, Peter & YOURDON, Edward. Análise baseada em Objetos. 2ª ed. Editora Campus, 1992.
Confira também
Artigos relacionados
-
Artigo
-
Artigo
-
Artigo
-
Artigo
-
Artigo