Modelagem de dados em Java com UML

Modelagem de dados em Java com UML

O Objetivo deste artigo é fornecer uma introdução à modelagem de Classes em Java utilizando diagramas UML. Neste exemplo iremos abordar o primeiro tipo de relacionamento aprendido em Orientação a Objetos: SER (É-UM) utilizado entre Classes e também entre Interfaces. Para tal iremos partir do principio, ou seja, o tipo mais “puro” de objeto Java, denominado JavaBean


Classe JavaBean

Classe Java de Entidade (Modelagem)

Características:
- Atributos privados.
- Construtor default (vazio)
- Sobrecarga de Construtor (Entrada de dados)
- Encapsulamento
- Sobrescrita dos métodos de Object
- toString
- equals
- hashCode
- Serialização (Opcional)

package heranca;

public class Cliente {

	private Integer idCliente;
	private String nome;

	public Cliente() {
	}

	public Cliente(Integer idCliente, String nome) {
		super();
		this.idCliente = idCliente;
		this.nome = nome;
	}

	@Override
	public String toString() {
		return idCliente + ", " + nome;
	}

	public Integer getIdCliente() {
		return idCliente;
	}
	public void setIdCliente(Integer idCliente) {
		this.idCliente = idCliente;
	}
	public String getNome() {
		return nome;
	}
	public void setNome(String nome) {
		this.nome = nome;
	}
}

Visibilidades:
- private Acesso somente dentro da Classe.
~ default Acesso somente por classes do mesmo pacote.
# protected Acesso por pacote e por herança.
+ public Acesso total.

Herança (É-UM)

package heranca;

public class PessoaFisica extends Cliente {

	private String cpf;

	public PessoaFisica() {
	}

	public PessoaFisica(Integer idCliente, String nome, String cpf) {
		super(idCliente, nome);
		this.cpf = cpf;
	}

	@Override
	public String toString() {
		return super.toString() + ", " + cpf;
	}

	public String getCpf() {
		return cpf;
	}
	public void setCpf(String cpf) {
		this.cpf = cpf;
	}
}

Implementação (É-UM)

Componente de programação OO totalmente abstrato. Tem como caracteristicas: Padronização.
- Interfaces Não possuem construtores.
- Seus atributos são final (constantes).
- Métodos são publicos e abstratos (não tem corpo).
- Quando uma classe implementa uma interface, ela é obrigada a fornecer corpo para os metodos da interface (desde que não seja uma classe abstrata).

package relacionamento;

public interface IArquivo {

	void abrirArquivo();
	void gravarArquivo(String conteudo);
	void fecharArquivo();
}

Quando uma Classe não abstrata (comum) herda (implementa) uma interface, esta é obrigada a fornecer corpo para os metodos da interface. Por exemplo:

package relacionamento;

public class Documento implements IArquivo {

	@Override
	public void abrirArquivo() {
		// TODO Auto-generated method stub
	}

	@Override
	public void gravarArquivo(String conteudo) {
		// TODO Auto-generated method stub
	}

	@Override
	public void fecharArquivo() {
		// TODO Auto-generated method stub
	}
}

UML, qualquer nome em itálico, representa algo abstrato ou interface.
No próximo artigo iremos estudar o segundo tipo de relacionamento entre Classes denominado TER (Todo/Parte) e suas variações como Agregação, Composição, Dependência e suas Multiplicidades.

package entity2;

public abstract class Automovel {

	private Integer idAutomovel;
	private String nome;

	public Automovel() {
	}

	public Automovel(Integer idAutomovel, String nome) {
		this.idAutomovel = idAutomovel;
		this.nome = nome;
	}

	@Override
	public String toString() {
		return idAutomovel + ", " + nome;
	}

	public Integer getIdAutomovel() {
		return idAutomovel;
	}
	public void setIdAutomovel(Integer idAutomovel) {
		this.idAutomovel = idAutomovel;
	}
	public String getNome() {
		return nome;
	}
	public void setNome(String nome) {
		this.nome = nome;
	}

	// Métodos abstratos
	public abstract void setFabricante(String fabricante);
	public abstract String getFabricante();
}    

Classes comuns herdando da Classe Abstrata

package entity2;

public class CarroEsportivo extends Automovel {

	private Integer ano;
	private String fabricante;

	public CarroEsportivo() {

	}

	public CarroEsportivo(Integer idAutomovel, String nome, Integer ano, String fabricante) {
		super(idAutomovel, nome);
		this.ano = ano;
		this.fabricante = fabricante;
	}

	@Override
	public String toString() {
		return super.toString() + ", " + ano + ", " + fabricante;
	}

	public Integer getAno() {
		return ano;
	}
	public void setAno(Integer ano) {
		this.ano = ano;
	}

	@Override
	public String getFabricante() {
		return fabricante;
	}

	@Override
	public void setFabricante(String fabricante) {
		this.fabricante = fabricante;
	}
}    
package entity2;

public class CarroExecutivo extends Automovel {

	private String modelo;
	private String fabricante;

	public CarroExecutivo() {

	}

	public CarroExecutivo(Integer idAutomovel, String nome, String modelo,
			String fabricante) {
		super(idAutomovel, nome);
		this.modelo = modelo;
		this.fabricante = fabricante;
	}

	@Override
	public String toString() {
		return super.toString() + ", " + modelo + ", " + fabricante;
	}

	public String getModelo() {
		return modelo;
	}
	public void setModelo(String modelo) {
		this.modelo = modelo;
	}

	@Override
	public String getFabricante() {
		return fabricante;
	}

	@Override
	public void setFabricante(String fabricante) {
		this.fabricante = fabricante;
	}
}    

Executando...

package main;

import entity2.Automovel;
import entity2.CarroEsportivo;
import entity2.CarroExecutivo;

public class Main {

	public static void main(String[] args) {

		Automovel a1 = new CarroEsportivo(1, "Ferrari", 2012, "Ferrari Italia");

		Automovel a2 = new CarroExecutivo(2, "C4", "Sedan", "Citroen");

		System.out.println(a1);
		System.out.println(a2);
	}
}    

No exemplo acima podemos dizer que CarroEsportivo É Automovel e CarroExecutivo É Automovel, portanto, a herança da Classe abstrata configura o uso de Polimorfismo. Note que Transformamos o objeto Automovel em CarroEsportivo e CarroExecutivo