Engenharia de Software
Alexandre Vasconcelos, André Santos,
Augusto Sampaio, Hermano Moura,
Paulo Borba
© Centro de Informática
Universidade Federal de Pernambuco
Estruturação do Código em
Camadas
Paulo Borba
Objetivo
Depois desta aula você será capaz de estruturar
o seu código em camadas, de forma a obter
melhor reuso e extensibilidade.
Vendo o código como uma caixa
preta...
Vendo o código como palavras
cruzadas...
G
D
COMUNICAÇÃO
I
D
NEGÓCIO
S
Vendo o código como um bolo...
com várias camadas!
Interface com o usuário
(GUI)
Comunicação
Negócio
Dados
Arquitetura em Camadas

Interface com o Usuário
 código

para a apresentação da aplicação
Comunicação
 código
para permitir acesso remoto aos serviços
da aplicação

Negócio
 código

inerente à aplicação sendo desenvolvida
Dados
 código
para acesso e manipulação de dados
Negócio
Dados
Negócio
Dados
Comunicação
Negócio
Benefícios da Arquitetura em
Camadas

Modularidade e seus benefícios:
 Dividir
para conquistar
 Separação de conceitos
 Reusabilidade
 Extensibilidade

Mudanças em uma camada não afetam as
outras, desde que as interfaces sejam
preservadas
 plug-and-play
Benefícios da Arquitetura em
Camadas

Uma mesma versão de uma camada
trabalhando com diferentes versões de outra
camada:
 várias GUIs para a mesma aplicação
 vários mecanismos de persistência
suportados pela mesma aplicação
 várias plataformas de distribuição para
acesso a uma mesma aplicação
Classes Básicas de Negócio
class Conta
implements PersistentObject,
Serializable {
private double saldo;
private String numero;
...
void creditar(double v) {
saldo = saldo + v;
}
void update() {...}
void access() {...}
}
Interfaces Negócio-Dados
interface ConjuntoDeContas {
void inserir(Conta conta)
throws RepositorioException,
ContaInvalidaException;
void atualizar(Conta conta)
throws RepositorioException,
ContaInvalidaException;
void remover(String num)
throws RepositorioException,
ContaInvalidaException;
Conta procurar(String num)
throws RepositorioException;
Conta getMaiorSaldo() throws RepositorioException;
IteradorContas getIterador();
}
Classes Coleção de Dados
class ConjuntoDeContasRelacional
implements ConjuntoDeContas {
private MecanismoPersistencia base;
ConjuntoDeContasRelacional(MecanismoDePersistencia mp){
base = mp;
}
Classes Coleção de Dados
void inserir(Conta c) throws RepositorioException,
ContaInvalidaException {
try{
if (c != null) c.update();
else throw new ContaInvalidaException();
} catch (DBRuntimeException e) {
throw new RepositorioException();
}
}
Classes Coleção de Dados
void atualizar(Conta c) throws RepositorioException,
ContaInvalidaException {
Conta conta1;
if (c != null)
try {
conta1 = this.procurar(c.getNumero());
conta1.atualizar(c);
conta1.update();
} catch (DBRuntimeException e) {
throw new RepositorioException();
}
else throw new ContaInvalidaException();
}
Classes Coleção de Dados
Conta procurar(String num)
throws RepositorioException {
Conta c;
try {
c = (Conta) Extent.all("Conta").where("numero=” +
num).element();
} catch (DBRuntimeException e) {
throw new RepositorioException();
}
return c;
}
Classes Coleção de Negócio
class CadastroDeContas {
private ConjuntoDeContas contas;
void CadastroDeContas(ConjuntoDeContas cContas) {
contas = cContas;
}
void creditar(String num, double val) throws
ContaInvalidaException, RepositorioException {
Conta c = contas.procurar(num);
c.creditar(val);
contas.atualizar(c);
}
Classes Coleção de Negócio
void cadastrar(Conta c)
throws ContaJaExisteException,
ContaInvalidaException,
RepositorioException {
if (c!=null) {
if (contas.existe(c.getNumero()))
throw new ContaJaExisteException();
else contas.inserir(c);
} else throw new ContaInvalidaException();
}
Interface Mecanismo de
Persistência
interface MecanismoPersistencia {
boolean conectar()
throws MecanismoPersistenciaException;
boolean desconectar()
throws MecanismoPersistenciaException;
boolean iniciarTransacao()
throws MecanismoPersistenciaException;
boolean confirmarTransacao()
throws MecanismoPersistenciaException;
boolean cancelarTransacao()
throws MecanismoPersistenciaException;
}
Classe Mecanismo de Persistência
class MecanismoPersistenciaBDR
implements MecanismoPersistencia {
MecanismoPersistenciaBDR (String tipoConexao,
String url, String login, String senha,
String classeDoDriver)
throws MecanismoPersistenciaException {
bd = new Database(tipoConexao,url,login,senha);
try {
Class.forName(classeDoDriver);
} catch(DBRuntimeException e) {
throw new MecanismoPersistenciaException();
}
Classe Fachada
class Banco {
private CadastroDeContas contas;
private MecanismoDePersistencia bd;
...
AplicacaoBancaria (CadastroDeContas cadContas, ...
MecanismoDePersistencia mp) {
contas = cadContas; ...
bd = mp;
}
Classe Fachada
void creditar(String num, double val) throws
ContaInexistenteException, RepositorioException {
try {
bd.iniciarTransacao();
contas.creditar(num,val);
bd.confirmarTransacao();
} catch(MecanismoPersistenciaException e){
System.out.println(EXC_CONEXAO);
bd.cancelarTransacao();
}
}
Interface da Fachada
public interface IBanco {
void creditar (String nConta, double valor)
throws CommunicationException,
ContaInexistenteException,
RepositorioException;
...
}
Adaptador Fonte

Isola a GUI da camada de comunicação
 obtém
referência ao objeto remoto
 delega invocação ao objeto remoto
 troca exceções RMI por exceção genérica
Adaptador Fonte
public class BancoSourceRMIAdapter implements IBanco {
private BancoTargetRMIAdapter banco;
public BancoSourceRMIAdapter()
throws CommunicationException{
try {
banco = (BancoTargetRMIAdapter)
Naming.lookup("//www.di.ufpe.br:2120/BankServer");
} catch (Exception e) {
e.printStackTrace();
throw new CommunicationException ( );
}
}
Adaptador Fonte
public void creditar(String nConta, double valor)
throws CommunicationException,
ContaInexistenteException {
try {
banco.creditar(nConta,valor);
} catch (RemoteException e){
throw new CommunicationException();
}
}
Interface do Adaptador Destino
public interface IBancoTargetRMIAdapter extends Remote{
void creditar(String nConta, double valor)
throws CommunicationException,
ContaInexistenteException,
RemoteException;
...
}
Adaptador Destino

Isola a camada de negócio da camada de
comunicação
 faz
papel de objeto remoto
 faz papel de inicializador
 delega invocação de método remoto a método
de negócio
Adaptador Destino
public class BancoTargetRMIAdapter
extends UnicastRemoteObject
implements IBancoTargetRMIAdapter {
private IBanco banco;
public BancoTargetRMIAdapter()
throws RemoteException,
InicializacaoBancoException {
banco = new Banco();
}
public void creditar(String nConta, double valor)
throws RemoteException, CommunicationException,
ContaInexistenteException {
banco.creditar(nConta, valor);
}
Engenharia de Software
Alexandre Vasconcelos, André Santos,
Augusto Sampaio, Hermano Moura,
Paulo Borba
© Centro de Informática
Universidade Federal de Pernambuco
Download

Implementação 2