Prévia do material em texto
TÉCNICAS DE
PROGRAMAÇÃO
Unidade 05
A Camada de Negócios – Padrões de Projeto
Leitura recomendada:
• Padrões de Arquitetura de Aplicações Corporativas; Martin
Fowler; pgs 46 a 51 e 120 a 133
• Padrões e Projeto Orientado a Objetos; Goodrich; pgs 177 a
214 e 383 a 408
Técnicas de Programação Faculdade de Informática/PUCRS 1
PADRÕES DE PROJETO
Técnicas de Programação Faculdade de Informática/PUCRS 2
Padrão Singleton: Definição
• Contexto:
• Todos os clientes necessitam acessar uma única instância
compartilhada da classe.
• Deve-se garantir que nenhuma instância adicional será criada
acidentalmente.
• Solução:
• Alternativa 1:
• Classe com todos os métodos e atributos estáticos.
• Alternativa 2:
• Definir uma classe com um construtor privado.
• A classe cria uma instância única de si mesma.
• Fornece-se um método estático que retorna uma referência para a
instância única.
Técnicas de Programação 3 Faculdade de Informática/PUCRS
Padrão Singleton
• Alternativa 1:
• Usar uma classe “static” tal como a classe “Math”
• Vantagens: acessível de qualquer ponto do programa.
• Desvantagem: não controla a quantidade de instâncias. Instância
única “hard-coded”.
• Complica se houver a necessidade de criar mais uma instância no
futuro.
Técnicas de Programação 4 Faculdade de Informática/PUCRS
Padrão Singleton
• Alternativa 2:
• Manter o construtor privado.
• Criar um atributo privado estático para manter a instância.
• Criar um método estático para ter acesso “global” a instância.
• Vantagem:
• permite trabalhar com mais de uma instância se for o caso, mas
controlando a quantidade.
Técnicas de Programação 5 Faculdade de Informática/PUCRS
Exemplo (variação 1)
class Spooler{
static Spooler instance;
private Spooler() {
//... Conteúdo do construtor ...
}
static public Spooler getInstance(){
if(instance == null)
instance = new Spooler();
return(instance);
}
// Outros métodos da classe ...
}
Técnicas de Programação 6 Faculdade de Informática/PUCRS
Exemplo (variação 2: threads)
class Spooler{
static Spooler instance;
private Spooler() {
//... Conteúdo do construtor ...
}
static synchronized public Spooler getInstance(){
if(instance == null)
instance = new Spooler();
return(instance);
}
// Outros métodos da classe ...
}
Técnicas de Programação 7 Faculdade de Informática/PUCRS
Exemplo (variação 3: clone)
class Spooler{
static Spooler instance;
private Spooler() {
//... Conteúdo do construtor ...
}
static synchronized public Spooler getInstance(){
if(instance == null)
instance = new Spooler();
return(instance);
}
public Object clone() {
throw new CloneNotSupportedException();
}
// Outros métodos da classe ...
}
Técnicas de Programação 8 Faculdade de Informática/PUCRS
Uso no exemplo do IRPF
• Uso do Singleton no validador de contribuinte
public class ValidadorContribuinte {
private static ValidadorContribuinte vc = null;
private ValidadorContribuinte() {
}
public static ValidadorContribuinte getInstance() {
if (vc == null) {
vc = new ValidadorContribuinte();
}
return (vc);
}
public void validaNome(String n) throws ValidadorContribuinteException{
...
}
... Outros métodos ...
}
Técnicas de Programação Faculdade de Informática/PUCRS 9
Padrão Fachada
• Fornece uma interface única para um conjunto de
interfaces de um subsistema. A fachada (facade) define
uma interface de mais alto nivel que torna o subsistema
mais fácil de usar.
Técnicas de Programação 10 Faculdade de Informática/PUCRS
Padrão Fachada: Definição
• Classificação: estrutural de objeto
• Contexto:
• Um sistema é composto por uma série de subsistemas que provém
um conjunto de serviços relacionados.
• A medida que o sistema evolui e o número de subsistemas cresce,
torna-se mais complexo o acesso ao conjunto de serviços.
• A maioria dos clientes não necessita ter acesso aos métodos mais
específicos de cada um dos subsistemas.
• Solução:
• Implementar uma classe que implementa uma fachada (facade),
abstraindo os detalhes de implementação dos serviços mais
solicitados para o conjunto de subsistemas.
• Esta classe serve de fachada. Abstrai a complexidade do uso
direto dos subsistemas deixando-os disponíveis para serem
acessados diretamente quando necessário.
Técnicas de Programação 11 Faculdade de Informática/PUCRS
Padrão Fachada: Diagrama
Técnicas de Programação 12 Faculdade de Informática/PUCRS
Uso no exemplo do IRPF
• No exemplo do IRPF um
Fachada foi usado para diminuir
o acoplamento entre as
camadas de apresentação e
negócios.
• Note que o controlador da
camada de apresentação
interage basicamente com a
“fachada” da camada de
negócios.
• A “fachada” solicita os serviços
dos demais objetos da camada
de negócios para atender as
demandas da camada de
apresentação.
• A camada de apresentação não
precisa conhecer os detalhes da
camada de negócios
Técnicas de Programação Faculdade de Informática/PUCRS 13
Uso no exemplo do IRPF
public class IrpfFachada {
private ContribuinteDAO cadContribuinte;
...
public double calcula(TipoCalculo t, String cpf) throws IrpfException {
CalculoIrpf ir = new CalculoIrpf();
ir.setTipo(t);
Contribuinte c = cadContribuinte.buscar(cpf);
if (c == null) {
throw new IrpfException("CPF inexistente: " + cpf);
}
return (ir.impostoDevido(c));
}
}
Técnicas de Programação Faculdade de Informática/PUCRS 14
Padrão Strategy
• Define uma familia de algoritmos, encapsula cada um e
permite que os mesmos sejam intercambiaveis. O padrão
Strategy permite que o algoritmo varie independente dos
clientes que o usam.
Técnicas de Programação 15 Faculdade de Informática/PUCRS
Padrão Strategy: Definição
• Classificação: comportamental de objeto
• Contexto:
• Uma classe (chamada de contexto) pode se beneficiar de diferentes
variantes de um algoritmo.
• Clientes da classe contexto as vezes fornecem versões próprias do
algoritmo.
• Solução:
• Definir uma interface que seja uma abstração do algoritmo. Chama-se
esta interface de Strategy.
• Classes concretas de estratégia implementam a interface Strategy.
Cada classe estratégia implementa uma versão do algoritmo.
• O cliente fornece um objeto de estratégia concreto para a classe
contexto.
• Sempre que o algoritmo tiver de ser executado, a classe contexto
chama os método apropriados do objeto estratégia.
Técnicas de Programação 16 Faculdade de Informática/PUCRS
Padrão Strategy: Diagrama
Técnicas de Programação 17 Faculdade de Informática/PUCRS
Uso no exemplo do IRPF
• Permite facilitar a
criação de novos
métodos de
cálculo;
• O “context” do
padrão é a
classe
Contribuinte. Ele
é quem usa as
diferentes
estratégias de
cálculo.
Técnicas de Programação Faculdade de Informática/PUCRS 18
Uso no exemplo do IRPF
public class Contribuinte {
private String nome;
...
private CalculoIrpf impostoDevido;
public Contribuinte(String nome,String cpf,int idade, int nroDep,double contrPrev,double totRend)
throws IllegalArgumentException{
...
this.contrPrev = contrPrev;
this.cpf = cpf;
this.idade = idade;
this.nome = nome;
this.nroDep = nroDep;
this.totRend = totRend;
this.impostoDevido = new CalculoIrpfSimplificado(); // Assume como default
}
public void defineCalculo(CalculoIrpf calc){impostoDevido = calc;
}
...
public double getImpostoDevido(){
return impostoDevido.calculaImposto(this);
}
}
Técnicas de Programação Faculdade de Informática/PUCRS 19
Padrão Factory
• Define uma interface para a criação de um objeto, mas
deixa as subclasses definirem a classe a ser instanciada.
O padrão faz com que a classe deixe o instanciamento
para as subclasses.
• É mais flexível que um construtor
• É possível criar objetos de subclasses e não apenas de uma
classe fixa
Técnicas de Programação 20 Faculdade de Informática/PUCRS
Padrão Factory: Definição
• Classificação: padrão de criação
• Contexto:
• Um tipo, que será chamado de creator, cria objetos de outro tipo,
que será chamado de product
• Subclasses do tipo creator necessitam criar diferentes tipos de
objetos product
• Os clientes não precisam conhecer o tipo exato dos objetos
product
Técnicas de Programação 21 Faculdade de Informática/PUCRS
Padrão Factory: Definição
• Solução:
• Defina um tipo creator que expresse os atributos comuns de todos
os criadores
• Defina um tipo product que expresse os atributos comuns de
todos os produtos
• Defina um método fabricante factoryMethod no tipo creator que
irá gerar objetos product
• Cada classe concreta de creator implementa o método fabricante
de maneira que ele retorne um objeto de uma classe product
concreta
Técnicas de Programação 22 Faculdade de Informática/PUCRS
Padrão Factory: Diagrama
Técnicas de Programação 23 Faculdade de Informática/PUCRS
Padrão Factory
• Observações:
• A Factory decide que tipo de instância retornar baseada em
alguma lógica de decisão.
• O tipo retornado não importa, porque todos implementam a mesma
interface.
• O algoritmo de decisão pode ser extremamente complexo, mas
normalmente é extremamente simples.
Técnicas de Programação 24 Faculdade de Informática/PUCRS
Padrão Factory
• Quando usar o padrão Factory
• A classe não consegue antecipar o tipo de objeto que deve ser
criado.
• A classe usa suas subclasses para especificar que tipo de objeto
criar.
• Se for o caso de localizar a lógica de criação das instâncias.
• É mais flexível que um construtor, pois permite criar objetos de
subclasses e não apenas de uma classe fixa.
Técnicas de Programação 25 Faculdade de Informática/PUCRS
Padrão Factory
• O padrão Factory pode ter variações:
• A classe base é abstrata e o padrão deve retornar uma classe
completa.
• A classe base contém os métodos default e só existem classes
derivadas para alguns casos (nos demais retorna a própria classe
base).
• O parâmetro passado para o Factory define explicitamente o tipo
de instância a ser criada.
Técnicas de Programação 26 Faculdade de Informática/PUCRS
Uso no exemplo do IRPF
• O Factory é
responsável
pela criação
dos objetos de
estratégia de
cálculo do
imposto
• Informa-se
para o Factory
o tipo de
cálculo
desejado
Técnicas de Programação Faculdade de Informática/PUCRS 27
Uso no exemplo do IRPF
public class CalculoIrpfFactory {
public static CalculoIrpf createInstance(TipoCalculo t) {
switch(t) {
case SIMPLIFICADO:
return new CalculoIrpfSimplificado();
case COMPLETO:
return new CalculoIrpfCompleto();
}
return null;
}
}
Técnicas de Programação 28 Faculdade de Informática/PUCRS
Uso no exemplo do IRPF
public class IrpfFachada {
...
public double calcula(TipoCalculo t, String cpf) throws
IrpfException {
Contribuinte contribuinte = cadContribuinte.buscar(cpf);
if (contribuinte == null) {
throw new IrpfException("CPF inexistente: " + cpf);
}
CalculoIrpf ir = CalculoIrpfFactory.createInstance(t);
contribuinte.defineCalculo(ir);
return contribuinte.getImpostoDevido();
}
...
}
Técnicas de Programação 29 Faculdade de Informática/PUCRS
Outros padrões
• Outros padrões interessantes:
• Iterator
• Adapter
• Decorator
• Composite
• Serão apresentados na sequencia
Técnicas de Programação Faculdade de Informática/PUCRS 30
Padrão Iterator
• Provê uma forma de acessar os elementos de um objeto
agregado sequencialmente sem expor a sua
implementação interna.
Técnicas de Programação 31 Faculdade de Informática/PUCRS
Padrão Iterator: Definição
• Classificação: comportamental de objeto
• Contexto:
• Um objeto (chamado de agregador) contém outros objetos
(chamados de elementos).
• Clientes necessitam acessar os elementos.
• O agregador não deve expor sua estrutura interna.
• Podem haver vários clientes que necessitam acesso simultâneo.
• Solução:
• Definir uma classe iteradora que retorna um elemento de cada vez.
• Cada objeto iterador necessita manter a posição do próximo
elemento a retornar.
• Se existirem diferentes variações de agregadores e iteradores, é
melhor que todos implementem uma interface comum.
Técnicas de Programação 32 Faculdade de Informática/PUCRS
Padrão Iterator: Diagrama
Técnicas de Programação 33 Faculdade de Informática/PUCRS
Padrão Adapter
• Converte a interface de uma classe na interface esperada
por uma classe cliente. O padrão Adapter permite que
certas classes trabalhem juntas o que não seria possível
de outra forma devido a incompatibilidade das interfaces
Técnicas de Programação 34 Faculdade de Informática/PUCRS
Padrão Adapter: Definição
• Classificação: estrutural de classe
• Contexto:
1. Deseja-se usar uma classe sem modificá-la. Chama-se esta
classe de “adaptável”.
2. O contexto onde deseja-se usar a classe requer uma interface
“alvo” diferente da que a classe adaptavel oferece.
3. A interface alvo e a interface da classe adaptável são
conceitualmente relacionadas
• Solução:
1. Definir uma classe adaptadora que implementa a interface
“alvo”.
2. A classe adaptadora mantém uma referência para a classe
adaptável. Ela traduz os métodos da interface alvo para os
métodos da adaptavel.
3. O cliente empacota a classe adaptável em um objeto
adaptador.
Técnicas de Programação 35 Faculdade de Informática/PUCRS
Padrão Adapter: Diagrama
Técnicas de Programação 36 Faculdade de Informática/PUCRS
Padrão Adapter: Exemplo
• Exemplo:
1. Suponha que você dispõe de uma classe capaz de
exibir o logotipo de sua empresa sobre um Canvas.
2. Agora você quer exibir esse logotipo em um
formulário, junto dos demais componentes. Para
tanto é necessário inseri-lo em um contêiner de
componentes (Ex: JPanel).
3. Problema: um JPanel aceita JComponent e não a
classe que você já tinha.
4. Solução: criar uma classe adaptadora que
implementa a interface JComponent.
Técnicas de Programação 37 Faculdade de Informática/PUCRS
Padrão Adapter: Exemplo
import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
public class CarIcon implements Icon{
private int width;
public CarIcon(int aWidth) {
width = aWidth;
}
public int getIconWidth(){
return width;
}
public int getIconHeight(){
return width / 2;
}
public void paintIcon(Component c, Graphics g, int x, int y) {
Graphics2D g2 = (Graphics2D) g;
Rectangle2D.Double body = new Rectangle2D.Double(x, y + width / 6, width - 1,
width / 6);
Ellipse2D.Double frontTire = new Ellipse2D.Double(x + width / 6, y + width / 3, width /
6, width / 6);
Ellipse2D.Double rearTire = new Ellipse2D.Double(x + width * 2 / 3, y + width / 3,
width / 6, width / 6);
Point2D.Double r1 = new Point2D.Double(x + width / 6, y + width / 6);
Point2D.Double r2 = new Point2D.Double(x + width / 3, y);
Point2D.Double r3 = new Point2D.Double(x + width * 2 / 3, y);
Point2D.Double r4 = new Point2D.Double(x + width *5 / 6, y + width / 6);
Line2D.Double frontWindshield = new Line2D.Double(r1, r2);
Line2D.Double roofTop = new Line2D.Double(r2, r3);
Line2D.Double rearWindshield = new Line2D.Double(r3, r4);
g2.fill(frontTire); g2.fill(rearTire);
g2.setColor(Color.red); g2.fill(body); g2.draw(frontWindshield);
g2.draw(roofTop);
g2.draw(rearWindshield);
}
}
Técnicas de Programação 38 Faculdade de Informática/PUCRS
Padrão Adapter: Exemplo
import java.awt.*;
import javax.swing.*;
public class IconAdapter extends JComponent{
private Icon icon;
public IconAdapter(Icon icon){
this.icon = icon;
}
public void paintComponent(Graphics g){
icon.paintIcon(this, g, 0, 0);
}
public Dimension getPreferredSize(){
return new Dimension(icon.getIconWidth(),icon.getIconHeight());
}
}
Técnicas de Programação 39 Faculdade de Informática/PUCRS
import java.awt.*;
import javax.swing.*;
public class IconAdapterTester{
public static void main(String[] args){
Icon icon = new CarIcon(300);
JComponent component = new IconAdapter(icon);
JFrame frame = new JFrame();
frame.setLayout(new FlowLayout(FlowLayout.CENTER));
frame.add(new JButton("Ok"));
frame.add(component);
frame.add(new JButton("Cancel"));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}
Padrão Adapter: Exemplo
Técnicas de Programação Faculdade de Informática/PUCRS 40
Padrão Adapter: Exemplo 2
• A interface da classe de acesso ao banco de dados
devolvia linhas de tabelas relacionais como resposta as
consultas.
• Usando o Adapter a nova interface já retorna os objetos
que representam as entidades do sistema.
Técnicas de Programação 41 Faculdade de Informática/PUCRS
Padrão Decorator
• Acrescenta responsabilidades adicionais em um objeto
dinamicamente. O padrão decorator fornece uma
alternativa flexível ao uso da herança para estender
funcionalidades.
Técnicas de Programação 42 Faculdade de Informática/PUCRS
Padrão Decorator: Definição
• Classificação: estrutural de objeto
• Contexto:
• Deseja-se ampliar a capacidade de uma classe. Chama-se a mesma
de classe componente.
• Um componente decorado pode ser usado da mesma forma que o
componente sem decoração.
• A classe componente não deseja ter nenhuma responsabilidade sobre
a decoração
• Existe um conjunto muito grande de possibilidades de decoração.
• Solução:
• Defini-se uma interface que seja uma abstração do componente.
• As classes de componentes concretos implementam esta interface.
• Classes de decoração também implementam esta interface.
• O objeto decorador gerencia o objeto que ele decora.
• Quando implementa um método da interface do componente, o
decorador usa o método do componente decorado e combina o
resultado com o efeito da decoração
Técnicas de Programação 43 Faculdade de Informática/PUCRS
Padrão Decorator: Diagrama
Técnicas de Programação 44 Faculdade de Informática/PUCRS
Padrão Decorator: Exemplo1
• Barra de rolagem Swing
JTextArea area = new JTextArea(10,25);
JScrollPane painel = new JScrollPane(area);
Técnicas de Programação 45 Faculdade de Informática/PUCRS
Padrão Decorator: Exemplo 2
Técnicas de Programação 46 Faculdade de Informática/PUCRS
Padrão Decorator: Exemplo 2
public interface Mensagem{
String getMsg();
}
public class MensagemDeTexto implements Mensagem{
private String texto;
public MensagemDeTexto(String umTexto){
texto = umTexto;
}
public String getMsg(){
return(texto);
}
}
Técnicas de Programação 47 Faculdade de Informática/PUCRS
Padrão Decorator: Exemplo 2
public class MensagemColchetes implements Mensagem{
private Mensagem mensagem;
public MensagemColchetes(Mensagem umaMensagem){
mensagem = umaMensagem;
}
public String getMsg(){
String aux = "[[[ ";
aux += mensagem.getMsg();
aux += " ]]]";
return(aux);
}
}
Técnicas de Programação 48 Faculdade de Informática/PUCRS
Padrão Decorator: Exemplo 2
public class MensagemMoldura implements Mensagem{
private Mensagem mensagem;
public MensagemMoldura(Mensagem umaMensagem){
mensagem = umaMensagem;
}
public String getMsg(){
String aux = ">>";
return(aux);
}
}
Técnicas de Programação 49 Faculdade de Informática/PUCRS
Padrão Decorator: Exemplo 2
public class App{
public static void main(String args[]){
MensagemDeTexto mt = new MensagemDeTexto("Aviso urgente");
MensagemMoldura mm = new MensagemMoldura(mt);
MensagemColchetes mc = new MensagemColchetes(mm);
System.out.println(mm.getMsg());
System.out.println(mc.getMsg());
}
}
Técnicas de Programação 50 Faculdade de Informática/PUCRS
Padrão Composite
• Mostra como combinar vários objetos em um objeto que
tem o mesmo comportamento que suas partes
Técnicas de Programação Faculdade de Informática/PUCRS 51
Padrão Composite: Definição
• Classificação: estrutural de objeto
• Contexto:
• Objetos primitivos podem ser combinados em objetos compostos
• Clientes podem tratar objetos compostos como um objeto primitivo
• Solução:
• Define uma interface (primitive) para abstrair objetos primitivos
• Objeto composto (composite) contém coleção de objetos primitivos
• Ambos objetos primitivos e objetos compostos implementam a
mesma interface
• Ao implementar um método da interface, o objeto composto aplica
o método a todos os objetos primitivos e combina os resultados
Técnicas de Programação Faculdade de Informática/PUCRS 52
Padrão Composite: Diagrama
Técnicas de Programação Faculdade de Informática/PUCRS 53
Técnicas de Programação Faculdade de Informática/PUCRS 54