Você está na página 1de 54

Técnicas de Programação Faculdade de Informática/PUCRS 1

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 2

PADRÕES DE PROJETO
Técnicas de Programação Faculdade de Informática/PUCRS 3

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 Faculdade de Informática/PUCRS 4

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 Faculdade de Informática/PUCRS 5

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 Faculdade de Informática/PUCRS 6

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 Faculdade de Informática/PUCRS 7

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 Faculdade de Informática/PUCRS 8

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 Faculdade de Informática/PUCRS 9

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 10

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 Faculdade de Informática/PUCRS 11

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 Faculdade de Informática/PUCRS 12

Padrão Fachada: Diagrama


Técnicas de Programação Faculdade de Informática/PUCRS 13

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 14

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 15

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 Faculdade de Informática/PUCRS 16

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 Faculdade de Informática/PUCRS 17

Padrão Strategy: Diagrama


Técnicas de Programação Faculdade de Informática/PUCRS 18

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 19

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 20

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 Faculdade de Informática/PUCRS 21

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 Faculdade de Informática/PUCRS 22

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 Faculdade de Informática/PUCRS 23

Padrão Factory: Diagrama


Técnicas de Programação Faculdade de Informática/PUCRS 24

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 Faculdade de Informática/PUCRS 25

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 Faculdade de Informática/PUCRS 26

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 Faculdade de Informática/PUCRS 27

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 28

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 Faculdade de Informática/PUCRS 29

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 Faculdade de Informática/PUCRS 30

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 31

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 Faculdade de Informática/PUCRS 32

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 Faculdade de Informática/PUCRS 33

Padrão Iterator: Diagrama


Técnicas de Programação Faculdade de Informática/PUCRS 34

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 Faculdade de Informática/PUCRS 35

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 Faculdade de Informática/PUCRS 36

Padrão Adapter: Diagrama


Técnicas de Programação Faculdade de Informática/PUCRS 37

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 Faculdade de Informática/PUCRS 38

Padrão Adapter: Exemplo


public void paintIcon(Component c, Graphics g, int x, int y) {
import java.awt.*; Graphics2D g2 = (Graphics2D) g;
import java.awt.geom.*; Rectangle2D.Double body = new Rectangle2D.Double(x, y + width / 6, width - 1,
import javax.swing.*; width / 6);
Ellipse2D.Double frontTire = new Ellipse2D.Double(x + width / 6, y + width / 3, width /
public class CarIcon implements Icon{ 6, width / 6);
private int width; Ellipse2D.Double rearTire = new Ellipse2D.Double(x + width * 2 / 3, y + width / 3,
width / 6, width / 6);
public CarIcon(int aWidth) {
width = aWidth; 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);
public int getIconWidth(){ Point2D.Double r4 = new Point2D.Double(x + width * 5 / 6, y + width / 6);
return width;
} Line2D.Double frontWindshield = new Line2D.Double(r1, r2);
Line2D.Double roofTop = new Line2D.Double(r2, r3);
public int getIconHeight(){ Line2D.Double rearWindshield = new Line2D.Double(r3, r4);
return width / 2;
} 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 Faculdade de Informática/PUCRS 39

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 Faculdade de Informática/PUCRS 40

Padrão Adapter: Exemplo


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);
}
}
Técnicas de Programação Faculdade de Informática/PUCRS 41

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 Faculdade de Informática/PUCRS 42

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 Faculdade de Informática/PUCRS 43

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 Faculdade de Informática/PUCRS 44

Padrão Decorator: Diagrama


Técnicas de Programação Faculdade de Informática/PUCRS 45

Padrão Decorator: Exemplo1


• Barra de rolagem Swing

JTextArea area = new JTextArea(10,25);


JScrollPane painel = new JScrollPane(area);
Técnicas de Programação Faculdade de Informática/PUCRS 46

Padrão Decorator: Exemplo 2


Técnicas de Programação Faculdade de Informática/PUCRS 47

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 Faculdade de Informática/PUCRS 48

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 Faculdade de Informática/PUCRS 49

Padrão Decorator: Exemplo 2


public class MensagemMoldura implements Mensagem{
private Mensagem mensagem;

public MensagemMoldura(Mensagem umaMensagem){


mensagem = umaMensagem;
}

public String getMsg(){


String aux = "<<< ";
aux += mensagem.getMsg();
aux += " >>>";
return(aux);
}
}
Técnicas de Programação Faculdade de Informática/PUCRS 50

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 Faculdade de Informática/PUCRS 51

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 52

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 53

Padrão Composite: Diagrama


Técnicas de Programação Faculdade de Informática/PUCRS 54

Você também pode gostar