Académique Documents
Professionnel Documents
Culture Documents
Índice
Nota Prévia ................................................................................................................... 3
Historial........................................................................................................................ 4
Padrões de Desenho GoF .............................................................................................. 5
Padrões de Criação ..................................................................8
Abstract Factory (Fábrica Abstracta) ..................................................................... 8
Builder (Fabricante) ............................................................................................ 14
Factory Method (Método-Fábrica)....................................................................... 19
Prototype (Protótipo)........................................................................................... 25
Singleton (Solitário) ............................................................................................ 31
Padrões Estruturais ................................................................ 34
Adapter (Adaptador) ........................................................................................... 34
Bridge (Ponte)..................................................................................................... 39
Composite (Composto)........................................................................................ 43
Decorator (Decorador) ........................................................................................ 47
Façade (Fachada) ................................................................................................ 51
Flyweight (Peso-Leve) ........................................................................................ 54
Proxy (Procurador).............................................................................................. 59
Padrões de Comportamento .................................................... 63
Chain of Responsibility (Cadeia de Responsabilidade) ........................................ 63
Command (Comando) ......................................................................................... 67
Interpreter (Interpretador).................................................................................... 71
Iterator (Iterador)................................................................................................. 75
Mediator (Mediador) ........................................................................................... 79
Memento (Memória) ........................................................................................... 83
Observer (Observador) ........................................................................................ 87
State (Estado)...................................................................................................... 92
Strategy (Estratégia)............................................................................................ 98
Template Method (Método-Modelo) ................................................................. 101
Visitor (Visitante) ............................................................................................. 104
Relações entre Padrões GoF .................................................. 109
Referências ............................................................................................................... 110
Anacleto Correia 2
IPS-ESTSetúbal Padrões de Desenho
Nota Prévia
O conteúdo deste documento resulta de compilação e tratamento de
elementos provenientes de diversas fontes, as quais se encontram
listadas nas “Referências”.
Anacleto Correia 3
IPS-ESTSetúbal Padrões de Desenho
Historial
Christopher Alexander descreve 250 padrões de desenho de
arquitectura, no livro “A Pattern Language: Towns, Buildings,
Construction”. A descrição de um padrão de desenho consiste na
apresentação e discussão de um determinado problema e na
descrição de uma solução que sirva para diversos problemas que
possam ser encontrados e que se encaixem no mesmo padrão.
Anacleto Correia 4
IPS-ESTSetúbal Padrões de Desenho
Anacleto Correia 5
IPS-ESTSetúbal Padrões de Desenho
Objectivo
De Criação Estrutural Comportamental
Classe Factory Method Adapter Interpreter
Template Method
Anacleto Correia 6
IPS-ESTSetúbal Padrões de Desenho
Anacleto Correia 7
IPS-ESTSetúbal Padrões de Desenho
Padrões de Criação
Participantes:
· AbstractFactory
o Declara uma interface para operações de criação de
produtos abstractos
· ConcreteFactory
o Implementa as operações de criação de objectos de
produtos concretos
· AbstractProduct
o Declara uma interface para um objecto do tipo produto
· Product
o Define um objecto do tipo produto a ser criado pela
correspondente fábrica concreta
o implementa a interface AbstractProduct
· Client
o Utiliza as interfaces declaradas pelas classes
AbstractFactory e AbstractProduct
Anacleto Correia 8
IPS-ESTSetúbal Padrões de Desenho
Anacleto Correia 9
IPS-ESTSetúbal Padrões de Desenho
Anacleto Correia 10
IPS-ESTSetúbal Padrões de Desenho
Exemplo
Anacleto Correia 11
IPS-ESTSetúbal Padrões de Desenho
Anacleto Correia 12
IPS-ESTSetúbal Padrões de Desenho
}
// "ProductB2"
class Lobo extends Carnivoro
{
// Métodos
public void devora( Herbivoro h )
{
// caça Bisonte
System.out.println( this + " caça o " + h );
}
public String toString()
{
return "Lobo";
}
}
// "Client"
class MundoAnimal
{
// Variáveis de Instância
private Herbivoro herbivoro;
private Carnivoro carnivoro;
// Constructores
public MundoAnimal( FabricaContinente fabrica )
{
carnivoro = fabrica.criarCarnivoro();
herbivoro = fabrica.criarHerbivoro();
}
// Métodos
public void executaCadeiaAlimentar()
{
herbivoro.pasta();
carnivoro.devora( herbivoro );
}
}
// Antilope pasta na savana
// Leao caça o Antilope
// Bisonte pasta na pradaria
// Lobo caça o Bisonte
Anacleto Correia 13
IPS-ESTSetúbal Padrões de Desenho
Builder (Fabricante)
Participantes:
· Builder
o Especifica uma interface abstracta de criação de
componentes de um objecto de Product
· ConcreteBuilder
o Constrói e monta as componentes de Product,
implementado a interface Builder
o Define e mantém referência da representação (instância
de Product) que cria
o Fornece uma interface para obtenção do produto criado
· Director
o Constrói um objecto utilizando a interface Builder
· Product
o Representa o objecto complexo a ser construído.
ConcreteBuilder constrói a representação interna do
produto e define o processo pelo qual é montado.
o Inclui classes que definem as componentes constituintes,
incluindo as interfaces para montagem dos componentes
no produto acabado
Anacleto Correia 14
IPS-ESTSetúbal Padrões de Desenho
Anacleto Correia 15
IPS-ESTSetúbal Padrões de Desenho
Exemplo
import java.util.Collections;
import java.util.HashMap;
// padrão Builder -- exemplo real
// “Client”
public class MainApp
{
public static void main(String[] args)
{
// Cria um concessionario com construtores de veiculos
Concessionario concessionario = new Concessionario();
VeiculoBuilder b1 = new ScooterBuilder();
VeiculoBuilder b2 = new AutomovelBuilder();
VeiculoBuilder b3 = new MotocicloBuilder();
// Constrói e mostra veiculos
concessionario.Construct(b1);
b1.getVeiculo().mostrar();
concessionario.Construct(b2);
b2.getVeiculo().mostrar();
concessionario.Construct(b3);
b3.getVeiculo().mostrar();
}
}
// "Director"
class Concessionario
{
// Builder utiliza um conjunto complexo de passos
public void Construct(VeiculoBuilder veiculoBuilder)
Anacleto Correia 16
IPS-ESTSetúbal Padrões de Desenho
{
veiculoBuilder.ConstroiEstrutura();
veiculoBuilder.ConstroiMotor();
veiculoBuilder.ConstroiRodas();
veiculoBuilder.ConstroiPortas();
}
}
// "Builder"
abstract class VeiculoBuilder
{
protected Veiculo veiculo;
public Veiculo getVeiculo()
{
return veiculo;
}
public abstract void ConstroiEstrutura();
public abstract void ConstroiMotor();
public abstract void ConstroiRodas();
public abstract void ConstroiPortas();
}
// "ConcreteBuilder1"
class MotocicloBuilder extends VeiculoBuilder
{
public void ConstroiEstrutura()
{
veiculo = new Veiculo("Motociclo");
veiculo.setCaracteristica("estrutura","Estrutura Motociclo");
}
public void ConstroiMotor()
{
veiculo.setCaracteristica("motor","500 cc");
}
public void ConstroiRodas()
{
veiculo.setCaracteristica("rodas","2");
}
public void ConstroiPortas()
{
veiculo.setCaracteristica("portas","0");
}
}
// "ConcreteBuilder2"
class AutomovelBuilder extends VeiculoBuilder
{
public void ConstroiEstrutura()
{
veiculo = new Veiculo("Automovel");
veiculo.setCaracteristica("estrutura","Estrutura Automovel");
}
public void ConstroiMotor()
{
veiculo.setCaracteristica("motor","2500 cc");
}
public void ConstroiRodas()
{
veiculo.setCaracteristica("rodas","4");
}
public void ConstroiPortas()
{
veiculo.setCaracteristica("portas","4");
}
Anacleto Correia 17
IPS-ESTSetúbal Padrões de Desenho
}
// "ConcreteBuilder3"
class ScooterBuilder extends VeiculoBuilder
{
public void ConstroiEstrutura()
{
veiculo = new Veiculo("Scooter");
veiculo.setCaracteristica("estrutura","Estrutura Scooter");
}
public void ConstroiMotor()
{
veiculo.setCaracteristica("motor","50 cc");
}
public void ConstroiRodas()
{
veiculo.setCaracteristica("rodas","2");
}
public void ConstroiPortas()
{
veiculo.setCaracteristica("portas","0");
}
}
// "Product"
class Veiculo
{
private String tipo;
private HashMap componentes = new HashMap();
// Constructor do Veiculo
public Veiculo(String tipo)
{
this.tipo = tipo;
}
public Object getCaracteristica(String key){
return componentes.get(new Integer(key.hashCode()));
}
public void setCaracteristica(String key, String value){
componentes.put(new Integer(key.hashCode()),value);
}
public void mostrar()
{
System.out.println("\n---------------------------");
System.out.println(" Tipo Veiculo: "+ tipo);
System.out.println(" Estrutura : " + componentes.get(new
Integer("estrutura".hashCode())));
System.out.println(" Motor : " + componentes.get(new
Integer("motor".hashCode())) );
System.out.println(" #Rodas: " + componentes.get(new
Integer("rodas".hashCode())) );
System.out.println(" #Portas : " + componentes.get(new
Integer("portas".hashCode())) );
}
}
Anacleto Correia 18
IPS-ESTSetúbal Padrões de Desenho
Participantes:
· Product
o Define uma interface de objectos que o método-fábrica
cria
· ConcreteProduct
o Implementa a interface do Product
· Creator
o Declara o método-fábrica, que retorna um objecto do tipo
Product. Creator pode também definir uma
implementação por omissão do método-fábrica, que
retorna por omissão um objecto ConcreteProduct.
o Pode evocar o método-fábrica para criar o objecto
Product.
· ConcreteCreator
o Sobre-escreve o método-fábrica para retornar uma
instância de ConcreteProduct.
Anacleto Correia 19
IPS-ESTSetúbal Padrões de Desenho
Exemplo
Anacleto Correia 20
IPS-ESTSetúbal Padrões de Desenho
// Methods
public Product FactoryMethod()
{
return new ConcreteProductB();
}
}
// "Client"
public class Factory_Estrutural {
// Main method
public static void main (String[] args) {
// Create director and builders
Creator ca = new ConcreteCreatorA();
Product pa = ca.FactoryMethod();
System.out.println ("Created " + pa);
Anacleto Correia 21
IPS-ESTSetúbal Padrões de Desenho
Anacleto Correia 22
IPS-ESTSetúbal Padrões de Desenho
// ConcreteProduct
class SummaryPage
extends Page {}
// ConcreteProduct
class BibliographyPage
extends Page {}
// ConcreteProduct
class ResultsPage
extends Page {}
// ConcreteProduct
class ConclusionPage
extends Page {}
// Creator
abstract class Document{
protected ArrayList pages = new ArrayList();
public Document() {
this.CreatePages();
}
public ArrayList getPages() {
return pages;
}
public String toString() {
return this.getClass().getName();
}
abstract public void CreatePages();
}
// ConcreteCreator
class Resume extends Document{
public void CreatePages() {
pages.add (new SkillsPage());
pages.add (new EducationPage());
pages.add (new ExperiencePage());
}
}
// ConcreteCreator
class Report extends Document
{
public void CreatePages()
{
pages.add (new IntroductionPage());
pages.add (new ResultsPage());
pages.add (new ConclusionPage());
pages.add (new SummaryPage());
pages.add (new BibliographyPage());
}
}
// Client
class Test {
public static void main( String[] args )
{
Document[] docs = new Document[ 2 ];
docs[0] = new Resume(); //Cria ConcreteCraetorA
docs[1] = new Report();// Cria ConcreteCreator B
for( int i=0; i<docs.length;i++)
{
System.out.println( "\n" + docs[i] + " ------- " );
ArrayList p =((Document)docs[i]).getPages();
for( int j=0; j<p.size();j++)
{
System.out.println(" " + p.get(j));
}
Anacleto Correia 23
IPS-ESTSetúbal Padrões de Desenho
}
}
}
/*
Resume -------
SkillsPage
EducationPage
ExperiencePage
Report -------
IntroductionPage
ResultsPage
ConclusionPage
SummaryPage
BibliographyPage
*/
Anacleto Correia 24
IPS-ESTSetúbal Padrões de Desenho
Prototype (Protótipo)
Participantes:
· Prototype
o Declara uma interface para se autoclonar
· ConcretePrototype
o Implementa uma interface para se autoclonar
· Client
o Cria um novo objecto pedindo ao protótipo para se
autoclonar
Exemplo
// Prototype pattern
import java.lang.Cloneable;
// Client test application
public class ClientApp
{
public static void main(String[] args)
{
// Create first instance and clone it
Prototype p1 = new ConcretePrototype1("I");
Anacleto Correia 25
IPS-ESTSetúbal Padrões de Desenho
Anacleto Correia 26
IPS-ESTSetúbal Padrões de Desenho
Exemplo
/*
Demonstração do padrão Prototype em que as novas cores
são criadas a partir de cópia das pré-existentes do mesmo tipo
*/
// Padrão Prototype -- examplo real
import java.util.Collections;
import java.lang.Cloneable;
import java.util.HashMap;
Anacleto Correia 27
IPS-ESTSetúbal Padrões de Desenho
// "Prototype"
abstract class CorPrototype
implements Cloneable {
public abstract Object clone();
}
// "ConcretePrototype"
class Cor
extends CorPrototype {
private int vermelha;
private int verde;
private int azul;
// Constructor
public Cor(int vermelha, int verde, int azul) {
this.vermelha = vermelha;
this.verde = verde;
this.azul = azul;
}
// Prototype manager
class GestorCor {
private HashMap componentes = new HashMap();
HashMap cors = new HashMap();
public CorPrototype getCaracteristica(Integer name) {
return (CorPrototype) cors.get(new Integer(name.hashCode()));
}
Anacleto Correia 28
IPS-ESTSetúbal Padrões de Desenho
Exemplo
Anacleto Correia 29
IPS-ESTSetúbal Padrões de Desenho
String colherName;
public void setColherName(String colherName) {
this.colherName = colherName;
}
public String getColherName() {return this.colherName;}
public Object clone()
{
Object object = null;
try {
object = super.clone();
} catch (CloneNotSupportedException exception) {
System.err.println("AbstractColher is not Cloneable");
}
return object;
}
}
// AbstractGarfo.java
// Two of Two Prototypes
abstract class AbstractGarfo implements Cloneable
{
String garfoName;
public void setGarfoName(String garfoName) {this.garfoName = garfoName;}
public String getGarfoName() {return this.garfoName;}
public Object clone()
{
Object object = null;
try {
object = super.clone();
} catch (CloneNotSupportedException exception) {
System.err.println("AbstractGarfo is not Cloneable");
}
return object;
}
}
// ColherSopa.java
// One of Two Concrete Prototypes extending the AbstractColher Prototype
class ColherSopa extends AbstractColher
{
public ColherSopa()
{
setColherName("Colher Sopa");
}
}
// SaladaColher.java
// Two of Two Concrete Prototypes extending the AbstractColher Prototype
class SaladaColher extends AbstractColher
{
public SaladaColher()
{
setColherName("Colher Salada");
}
}
// GarfoSalada.java
// The Concrete Prototype extending the AbstractGarfo Prototype
class GarfoSalada extends AbstractGarfo
{
public GarfoSalada()
{
setGarfoName("Garfo Salada");
}
}
Anacleto Correia 30
IPS-ESTSetúbal Padrões de Desenho
Singleton (Solitário)
Este padrão visa garantir que uma classe possui apenas uma
instância. Assim, um singleton possui construtor privado (ou
protegido) e um método obterInstancia(), que deve ser
sincronizado para que duas threads não o executem ao mesmo
tempo. Quando executado pela primeira vez, cria a instância e grava-
a numa propriedade static da classe, retornando esta mesma
propriedade sempre que requsitada pelo obterInstancia().
Participantes:
· Singleton
o Define o método de classe Instance (ou
obterInstancia()) que permite aos clientes acederem à
sua única instância.
o Responsável por criar e manter a sua única instância.
Anacleto Correia 31
IPS-ESTSetúbal Padrões de Desenho
Exemplo
// construtor privados
private GlobalVars() {
// campos da classe podem ser
// normalmente inicializados
inteiro = 0;
real = -1;
}
Anacleto Correia 32
IPS-ESTSetúbal Padrões de Desenho
public TestaGlobalVars() {
globais = GlobalVars.getInstance();
}
Duplicado
inteiro = -50
real = 30.69
inteiro = 20
real = -10.85
1/a Instancia
inteiro = 20
real = -10.85
*/
Anacleto Correia 33
IPS-ESTSetúbal Padrões de Desenho
Padrões Estruturais
Adapter (Adaptador)
Participantes:
· Target
o Define o domínio específico da interface que Client irá
utilizar.
· Adapter
o Adapta a interface de Adaptee à interface de Target.
· Adaptee
o Define uma interface existente que necessita de ser
adaptada.
· Client
o Colabora com objectos que estejam conforme a interface
de Target.
Anacleto Correia 34
IPS-ESTSetúbal Padrões de Desenho
Anacleto Correia 35
IPS-ESTSetúbal Padrões de Desenho
Exemplo
// Padrão Adapter
// "Target"
class Composto {
protected String nome;
protected float pontoEbulicao;
protected float pontoLiquidificacao;
protected double pesoMolecular;
protected String formulaMolecular;
// Constructor
public Composto(String nome) {
this.nome = nome;
}
// "Adapter"
class CompostoRico
extends Composto {
private BaseBadosQuimica banco;
// Constructor
public CompostoRico(String nome) {
super(nome);
}
super.mostrar();
Anacleto Correia 36
IPS-ESTSetúbal Padrões de Desenho
// "Adaptee"
class BaseBadosQuimica {
// A Base de Dados com 'API legada'
public float getPontoCritico(String compound, String point) {
float temperatura = 0.0F;
// Ponto de Liquidificação
if (point.compareTo("L") == 0) {
switch (compound.toLowerCase().charAt(1)) {
case 'g':
temperatura = 0.0F;
break; // "água"
case 'e':
temperatura = 5.5F;
break; //"benzina"
case 'l':
temperatura = -114.1F;
break; //"alcool"
}
}
// Ponto de ebulição
else {
switch (compound.toLowerCase().charAt(1)) {
case 'g':
temperatura = 100.0F;
break; // "água"
case 'e':
temperatura = 80.1F;
break; //"benzina"
case 'l':
temperatura = 78.3F;
break; //"alcool"
}
}
return temperatura;
}
switch (compound.toLowerCase().charAt(1)) {
case 'g':
structure = "H20";
break; // "água"
case 'e':
structure = "C6H6";
break; //"benzina"
case 'l':
structure = "C2H6O2";
break; //"alcool"
}
return structure;
}
Anacleto Correia 37
IPS-ESTSetúbal Padrões de Desenho
// aplicação Client
class AdapterPat {
public static void main(String[] args) {
// componente químico não adaptado
Composto coisa = new Composto("Desconhecido");
coisa.mostrar();
Anacleto Correia 38
IPS-ESTSetúbal Padrões de Desenho
Bridge (Ponte)
Anacleto Correia 39
IPS-ESTSetúbal Padrões de Desenho
Exemplo
// --------------- Bridge
// Separar a abstracção da sua implementação para que cada uma
// possa variar independentemente.
//Abstraction
class Pilha {
protected ImplementacaoPilha pi;
public Pilha(String s) {
if (s.equals("java")) {
pi = new PilhaJava();
}
else {
pi = new PilhaArray();
}
}
public Pilha() {
this("java");
}
public void push(int in) {
pi.push(new Integer(in));
}
public int pop() {
return ( (Integer) pi.pop()).intValue();
}
public boolean isEmpty() {
return pi.empty();
}
}
//RefinedAbstraction
class PilhaCrescente
extends Pilha {
private int _totalRejeitados = 0;
public PilhaCrescente() {
Anacleto Correia 40
IPS-ESTSetúbal Padrões de Desenho
super("java");
}
public PilhaCrescente(String s) {
super(s);
}
public int reportaRejeitados() {
return _totalRejeitados;
}
public void push(int in) {
if (!pi.empty() && in > ( (Integer) pi.peek()).intValue()) {
_totalRejeitados++;
}
else {
pi.push(new Integer(in));
}
}
}
// Implementor
interface ImplementacaoPilha {
Object push(Object o);
Object peek();
boolean empty();
Object pop();
}
// ConcreteImplementorA
class PilhaJava extends java.util.Stack implements
ImplementacaoPilha{}
// ConcreteImplementorB
class PilhaArray implements ImplementacaoPilha {
private Object[] _items = new Object[20];
private int _total = -1;
public Object push(Object o) { return _items[++_total] = o; }
public Object peek() { return _items[_total]; }
public Object pop() {return _items[_total--]; }
public boolean empty() { return _total == -1;}
}
// Client
class TestBridge {
public static void main(String[] args) {
Pilha[] pilhas = {
new Pilha("java"), new PilhaCrescente("java"),
new Pilha("meu"),new PilhaCrescente("meu") };
for (int i = 0, num; i < 20; i++) {
num = (int) (Math.random() * 1000) % 40;
for (int j = 0; j < pilhas.length; j++) {
pilhas[j].push(num);
}
}
for (int i = 0, num; i < pilhas.length; i++) {
while (!pilhas[i].isEmpty()) {
System.out.print(pilhas[i].pop() + " ");
}
System.out.println();
}
System.out.println("O total de elementos rejeitados é "
+ ( (PilhaCrescente) pilhas[1]).reportaRejeitados());
}
}
/*
29 28 38 8 0 31 3 15 18 5 15 34 23 3 35 38 19 32 4 21
0 3 3 4 21
Anacleto Correia 41
IPS-ESTSetúbal Padrões de Desenho
29 28 38 8 0 31 3 15 18 5 15 34 23 3 35 38 19 32 4 21
0 3 3 4 21
O total de elementos rejeitados é 15
*/
Anacleto Correia 42
IPS-ESTSetúbal Padrões de Desenho
Composite (Composto)
Participantes:
· Component
o Declara a interface para objectos na composição.
o Implementa conforme apropriado, o comportamento por
omissão da interface comum a todas as classes.
o Declara uma interface para acesso e gestão dos
componentes filhos.
o (opcional) define uma interface para acesso ao
componente pai, na estrutura recursiva, e implementa-a
caso apropriado.
· Leaf
o Representa os objectos folha na composição. Uma folha
não tem filhos.
o Define o comportamento dos objectos primitivos na
composição.
· Composite
o Define o comportamento dos componentes que têm
filhos.
o Armazena os componentes filhos.
o Implementa os métodos relacionados com os filhos, na
interface Component.
· Client
o Manipula objectos na composição através da interface
Component.
Anacleto Correia 43
IPS-ESTSetúbal Padrões de Desenho
Anacleto Correia 44
IPS-ESTSetúbal Padrões de Desenho
Exemplo
//COMPOSITE
interface Componente {void escreve();}
class Folha implements Componente {
private int _valor;
public Folha(int val) { _valor = val; }
public void escreve() {
System.out.print(_valor + " ");
}
}
abstract class No implements Componente {
private Componente[] _filhos = new Componente[9];
private int _total = 0;
private int _valor;
public No(int val) { _valor = val; }
public void add(Componente c) { _filhos[_total++] = c; }
public void escreve() {
System.out.print(_valor + " ");
for (int i=0; i < _total; i++) {
_filhos[i].escreve();
}
}
}
class Linha extends No {
public Linha(int val) { super(val); }
public void escreve() {
System.out.print("Linha");
super.escreve();
}
Anacleto Correia 45
IPS-ESTSetúbal Padrões de Desenho
}
class Coluna extends No {
public Coluna(int val) { super(val); }
public void escreve() {
System.out.print("Coluna");
super.escreve();
}
}
public class CompostoDemo {
public static void main(String[] args) {
Componente primei = new Linha(1);
Componente segund = new Coluna(2);
Componente tercei = new Coluna(3);
Componente quarto = new Linha(4);
Componente quinto = new Linha(5);
primei.add(segund);
primei.add(tercei);
tercei.add(quarto);
tercei.add(quinto);
primei.add(new Folha(6));
segund.add(new Folha(7));
tercei.add(new Folha(8));
quarto.add(new Folha(9));
quinto.add(new Folha(10));
primei.escreve();
}
}
// Linha1 Coluna2 7 Coluna3 Linha4 9 Linha5 10 8 6
Anacleto Correia 46
IPS-ESTSetúbal Padrões de Desenho
Decorator (Decorador)
Participantes:
· Component
o Define a interface dos objectos que podem ter
responsabilidades adicionadas de forma dinâmica.
· ConcreteComponent
o Define um objecto ao qual mais responsabilidades podem
ser adicionadas.
· Decorator
o Mantém a referência para um objecto Component e
define a interface que está conforme a interface
Component.
· ConcreteDecorator
o Adiciona responsabilidades ao componente.
Anacleto Correia 47
IPS-ESTSetúbal Padrões de Desenho
Anacleto Correia 48
IPS-ESTSetúbal Padrões de Desenho
Exemplo
// Padrão Decorator
// Componente
interface Componente { void desenha(); }
// ConcreteComponent
class Texto implements Componente {
private int comprimento, altura;
public Texto(int c, int a) {
comprimento = c; altura = a;
}
public void desenha() {
System.out.println("Texto: " + comprimento +
", " + altura);
}
}
// Decorator
abstract class Decorador implements Componente {
private Componente obj;
public Decorador(Objecto o) { obj = o; }
public void desenha() { obj.desenha(); }
}
// ConcreteDecoratorA
class Borda extends Decorador {
public Borda(Componente o) { super(o); }
public void desenha() {
Anacleto Correia 49
IPS-ESTSetúbal Padrões de Desenho
super.desenha();
System.out.println(" DecoraçãoBorda");
}
}
// ConcreteDecoratorB
class Cerca extends Decorador {
public Cerca(Componente o) { super(o); }
public void desenha() {
super.desenha();
System.out.println(" DecoraçãoCerca");
}
}
// Client
public class DecoratorPattern {
public static void main(String[] args) {
Componente obj = new Borda(
new Borda(
new Cerca(
new Texto(80,24))));
obj.desenha();
}
}
// Texto: 80, 24
// DecoraçãoCerca
// DecoraçãoBorda
// DecoraçãoBorda
Anacleto Correia 50
IPS-ESTSetúbal Padrões de Desenho
Façade (Fachada)
Participantes:
· Facade
o Sabe que classes do subsistema são responsáveis pelo
pedido.
o Delega os pedidos do cliente nos objectos apropriados do
subsistema.
· classes do Subsistema
o Implementam as funcionalidades do subsistema.
o Levam a cabo o trabalho atribuído ao objecto Facade.
o Não têm conhecimento do objecto Facade e não guardam
dele qualquer referência.
Anacleto Correia 51
IPS-ESTSetúbal Padrões de Desenho
Exemplo
// aplicação Cliente
public class patFacade {
public static void main(String[] args) {
// Facade
PedidoEmprestimo pedidoEmprestimo = new PedidoEmprestimo();
// Avalia se o cliente é eligível para obtenção de empréstimo
Cliente cliente = new Cliente("Ana Silva");
boolean eligivel = pedidoEmprestimo.ehEligivel(cliente, 125000);
Anacleto Correia 52
IPS-ESTSetúbal Padrões de Desenho
// propriedade
public String getName() {
return name;
}
}
// "Facade"
class PedidoEmprestimo {
private Banco banco = new Banco();
private Emprestimo emprestimo = new Emprestimo();
private Credito credito = new Credito();
Anacleto Correia 53
IPS-ESTSetúbal Padrões de Desenho
Flyweight (Peso-Leve)
Participantes:
· Flyweight
o Declara uma interface através da qual os flyweights
podem receber e actuar em estado extrínseco.
· ConcreteFlyweight
o Implementa a interface Flyweight e adiciona
armazenamento para o estado intrínseco, caso haja. Um
objecto ConcreteFlyweight deve ser partilhado. Qualquer
estado que armazene deve ser intrínseco, isto é, deve ser
independente do contexto do objecto ConcreteFlyweight.
· UnsharedConcreteFlyweight
o Nem todas as subclasses Flyweight têm que ser
partilhadas. A interface Flyweight permite a partilha, mas
não a obriga. É comum que os objectos
UnsharedConcreteFlyweight tenham objectos
ConcreteFlyweight como filhos num determinado nível da
estrutura do objecto flyweight.
· FlyweightFactory
o Cria e gere objectos flyweight
o Assegura que os flyweights são apropriadamente
partilhados. Quando um cliente solicita um flyweight, os
objectos FlyweightFactory fornecem uma instância
existente ou criam uma, caso não exista.
· Client
o Mantém referência(s) para flyweight(s).
o Calcula ou armazena o estado extrínseco do(s)
flyweight(s).
Anacleto Correia 54
IPS-ESTSetúbal Padrões de Desenho
Anacleto Correia 55
IPS-ESTSetúbal Padrões de Desenho
Exemplo
// Padrão Flyweight
import java.util.HashMap;
// aplicação Cliente
public class patFlyweigh {
public static void main(String[] args) {
// Construir um documento com texto
String documento = "AAZZBBZB";
char[] chars = documento.toCharArray();
CaracterFabrica f = new CaracterFabrica();
// estado extrínseco
int apontadorTamanho = 10;
// Para cada carácter usar um objecto flyweight
for (int i = 0; i < chars.length; i++) {
apontadorTamanho++;
Caracter caracter = f.getCaracter(chars[i]);
caracter.mostrar(apontadorTamanho);
}
}
}
// "FlyweightFactory"
class CaracterFabrica {
private HashMap characters = new HashMap();
public Caracter getCaracter(char key) {
// Uses "lazy initialization"
Caracter caracter = (Caracter) characters.get(new Character(key));
if (caracter == null) {
switch (key) {
case 'A':
caracter = new CaracterA();
Anacleto Correia 56
IPS-ESTSetúbal Padrões de Desenho
break;
case 'B':
caracter = new CaracterB();
break;
//...
case 'Z':
caracter = new CaracterZ();
break;
}
characters.put(new Character(key), caracter);
}
return caracter;
}
}
// "Flyweight"
abstract class Caracter {
protected char simbolo;
protected int comprimento;
protected int altura;
protected int ascendente;
protected int descendente;
protected int apontadorTamanho;
// "ConcreteFlyweight"
class CaracterA
extends Caracter {
// Constructor
public CaracterA() {
this.simbolo = 'A';
this.altura = 100;
this.comprimento = 120;
this.ascendente = 70;
this.descendente = 0;
}
// "ConcreteFlyweight"
class CaracterB
extends Caracter {
// Constructor
public CaracterB() {
this.simbolo = 'B';
this.altura = 100;
this.comprimento = 140;
this.ascendente = 72;
this.descendente = 0;
}
Anacleto Correia 57
IPS-ESTSetúbal Padrões de Desenho
// ... C, D, E, etc.
// "ConcreteFlyweight"
class CaracterZ
extends Caracter {
// Construtor
public CaracterZ() {
this.simbolo = 'Z';
this.altura = 100;
this.comprimento = 100;
this.ascendente = 68;
this.descendente = 0;
}
Anacleto Correia 58
IPS-ESTSetúbal Padrões de Desenho
Proxy (Procurador)
Participantes:
· Proxy
o Mantém a referência que permite à proxy aceder ao
objecto real. A Proxy pode-se referir ao Subject se as
interfaces de RealSubject e Subject forem as mesmas.
o Fornece uma interface idêntica a Subject para que a
proxy possa ser substituída pelo objecto real.
o Controla o acesso ao objecto real podendo ser
responsável pela sua criação e remoção.
o Outras responsabilidades dependem do tipo de proxy:
§ Proxies remotas são responsáveis por codificar o
pedido e os seus argumentos, e enviá-lo codificado
ao objecto real, num diferente espaço de endereço.
§ Proxies virtuais podem fazer cache de informação
adicional acerca do objecto real, para que se possa
adiar o acesso ao mesmo.
§ Proxies de protecção verificam se quem a evoca
tem privilégios de acesso necessários para efectuar
o pedido.
· Subject
Anacleto Correia 59
IPS-ESTSetúbal Padrões de Desenho
Anacleto Correia 60
IPS-ESTSetúbal Padrões de Desenho
Exemplo
// Padrão Proxy
// aplicação Cliente
public class PatProxy {
public static void main(String[] args) {
// Cria proxy math
IMath p = new MathProxy();
// Fazer os cálculos
System.out.println("4 + 2 = " + p.adicionar(4, 2));
System.out.println("4 - 2 = " + p.subtrair(4, 2));
System.out.println("4 * 2 = " + p.multiplicar(4, 2));
System.out.println("4 / 2 = " + p.dividir(4, 2));
}
}
// "Subject"
interface IMath {
double adicionar(double x, double y);
double subtrair(double x, double y);
double multiplicar(double x, double y);
double dividir(double x, double y);
}
// "RealSubject"
class Math
implements IMath {
public double adicionar(double x, double y) {
return x + y;
}
Anacleto Correia 61
IPS-ESTSetúbal Padrões de Desenho
return x - y;
}
Anacleto Correia 62
IPS-ESTSetúbal Padrões de Desenho
Padrões de Comportamento
Participantes:
· Handler
o Define uma interface para tratar os pedidos
o (opcional) implementa a ligação ao sucessor
· ConcreteHandler
o Trata os pedidos pelos quais é responsável
o Pode aceder ao seu sucessor
o Se o ConcreteHandler pode tratar o pedido, trata-o; caso
contrário envia-o ao seu sucessor
· Client
o Inicia o pedido a um objecto ConcreteHandler na cadeia
Anacleto Correia 63
IPS-ESTSetúbal Padrões de Desenho
Exemplo
Anacleto Correia 64
IPS-ESTSetúbal Padrões de Desenho
// "Handler"
abstract class Aprovador {
private String nome;
protected Aprovador sucessor;
// "ConcreteHandler"
class Director
extends Aprovador {
public Director(String nome) {
super(nome);
}
// "ConcreteHandler"
class VicePresidente
extends Aprovador {
public VicePresidente(String nome) {
super(nome);
}
// "ConcreteHandler"
class Presidente
extends Aprovador {
public Presidente(String nome) {
super(nome);
}
Anacleto Correia 65
IPS-ESTSetúbal Padrões de Desenho
// Detalhe do Pedido
class Compra {
private int numero;
private double valor;
private String finalidade;
// Construtor
public Compra(int numero, double valor, String finalidade) {
this.numero = numero;
this.valor = valor;
this.finalidade = finalidade;
}
// Propriedades
public double getValor() {
return valor;
}
int getNumero() {
return numero;
}
}
/*
Director Pedro aprovou pedido nº2034
Presidente Maria aprovou pedido nº2035
Pedido nº2036 requer uma reunião com o Presidente!
*/
Anacleto Correia 66
IPS-ESTSetúbal Padrões de Desenho
Command (Comando)
Participantes:
· Command
o Declara uma interface para execução de uma operação
· ConcreteCommand
o Define uma ligação entre o objecto Receiver e uma acção
o Implementa o método Execute, evocando as
correspondentes operações no Receiver
· Client
o Cria um objecto ConcreteCommand e estabelece o seu
receptor
· Invoker
o Pede ao comando para tomar conta do pedido
· Receiver
o Sabe como executar as operações associadas à realização
do pedido.
Anacleto Correia 67
IPS-ESTSetúbal Padrões de Desenho
Exemplo
// Command
interface Command {
void executar();
}
// Receiver
// Sabe como executar as operações associadas a um pedido.
// Qualquer classe pode actuar como Receiver.
Anacleto Correia 68
IPS-ESTSetúbal Padrões de Desenho
class ReceptorOla {
public void action() {
System.out.print("\nSou o Receiver de Ola!");
}
}
// Receiver
class ReceptorMundo {
public void faz() {
System.out.print("\nSou o Receiver de Mundo!");
}
}
// Receiver
class ReceptorEuSou {
public void diz() {
System.out.print("\nSou o Receiver de EuSou!");
}
}
// ConcreteCommand
//Define a ligação entre uma acção e o objecto receptor
//Invoca as operações correspondentes no receptor
class Ola
implements Command {
ReceptorOla r;
public Ola(ReceptorOla r) {
this.r = r;
}
// Invoker
// Pede a Command para tratar o seu pedido
class Macro {
private List pedidos = new ArrayList();
Anacleto Correia 69
IPS-ESTSetúbal Padrões de Desenho
// Client
// Cria o ConcreteCommand e define o seu receptor
public class CommandPattern {
private static Macro macro = new Macro();
public static void teste() {
macro.add(new Ola(new ReceptorOla()));
macro.add(new Mundo(new ReceptorMundo()));
macro.add(new EuSou(new ReceptorEuSou()));
macro.correr();
}
Anacleto Correia 70
IPS-ESTSetúbal Padrões de Desenho
Interpreter (Interpretador)
Participantes:
· AbstractExpression
o Declara uma interface para execução de um método.
· TerminalExpression
o Implementa o método Interpret associado com símbolos
terminais da gramática.
o É necessária uma instância para cada símbolo terminal na
frase.
· NonterminalExpression
o É necessária uma destas classes para cada regra R ::=
R1R2...Rn da gramática.
o Mantém variáveis de instância do tipo AbstractExpression
para cada um dos símbolos R1 a Rn.
o Implementa o método Interpret para símbolos não
terminais na gramática. Interpret tipicamente evoca-se a
si próprio recursivamente nas variáveis representando R1
a Rn.
· Context
o Contém informação que é global ao Interpreter.
· Client
o Constrói (ou é dada) uma árvore de sintaxe abstracta
representando uma frase particular na linguagem que a
gramática define. A árvore de sintaxe abstracta é
montada de instâncias das classes NonterminalExpression
e TerminalExpression.
o Evoca o método Interpret.
Anacleto Correia 71
IPS-ESTSetúbal Padrões de Desenho
Anacleto Correia 72
IPS-ESTSetúbal Padrões de Desenho
Exemplo
// Padrão Interpret
import java.util.ArrayList;
// aplicação Cliente
public class PatInterp {
public static void main(String[] args) {
String romano = "MCMXXVIII";
Contexto contexto = new Contexto(romano);
// Construir a 'parse tree'
ArrayList arvore = new ArrayList();
arvore.add(new ExpressaoMilhares());
arvore.add(new ExpressaoCentenas());
arvore.add(new ExpressaoDezenas());
arvore.add(new ExpressaoUnidades());
// Interpret
for (int i=0;i<arvore.size();i++ )
{
Expressao exp= (Expressao) arvore.get(i);
exp.interpretar(contexto);
}
System.out.println(romano + " = " + contexto.getOutput());
}
}
// "Context"
class Contexto
{
private String input;
private int output;
// Construtor
public Contexto(String input)
{
this.input = input;
}
// Propriedades
public String getInput() {
return input;
}
public void setInput(String value) {
input = value;
}
public int getOutput() {
return output;
}
// "AbstractExpression"
abstract class Expressao
{
public void interpretar(Contexto contexto)
{
if (contexto.getInput().length() == 0)
return;
if (contexto.getInput().startsWith(nove()))
{
contexto.setOutput( contexto.getOutput()+ (9 * multiplicador()));
contexto.setInput( contexto.getInput().substring(2));
}
else if (contexto.getInput().startsWith(quatro()))
{
contexto.setOutput(contexto.getOutput()+ (4 * multiplicador()));
contexto.setInput( contexto.getInput().substring(2));
}
else if (contexto.getInput().startsWith(cinco()))
{
contexto.setOutput(contexto.getOutput()+ (5 * multiplicador()));
contexto.setInput( contexto.getInput().substring(1));
}
while (contexto.getInput().startsWith(um()))
Anacleto Correia 73
IPS-ESTSetúbal Padrões de Desenho
{
contexto.setOutput(contexto.getOutput()+ (1 * multiplicador()));
contexto.setInput( contexto.getInput().substring(1));
}
}
public abstract String um();
public abstract String quatro();
public abstract String cinco();
public abstract String nove();
public abstract int multiplicador();
}
// Verificação dos Milhares para o numero romano M
// "TerminalExpression"
class ExpressaoMilhares extends Expressao
{
public String um() { return "M"; }
public String quatro(){ return " "; }
public String cinco(){ return " "; }
public String nove(){ return " "; }
public int multiplicador() { return 1000; }
}
// Verificação das centenas C, CD, D or CM
// "TerminalExpression"
class ExpressaoCentenas extends Expressao
{
public String um() { return "C"; }
public String quatro(){ return "CD"; }
public String cinco(){ return "D"; }
public String nove(){ return "CM"; }
public int multiplicador() { return 100; }
}
// Verificação das dezenas para X, XL, L and XC
// "TerminalExpression"
class ExpressaoDezenas extends Expressao
{
public String um() { return "X"; }
public String quatro(){ return "XL"; }
public String cinco(){ return "L"; }
public String nove(){ return "XC"; }
public int multiplicador() { return 10; }
}
// Verificação das unidades para I, II, III, IV, V, VI, VI, VII, VIII, IX
// "TerminalExpression"
class ExpressaoUnidades extends Expressao
{
public String um() { return "I"; }
public String quatro(){ return "IV"; }
public String cinco(){ return "V"; }
public String nove(){ return "IX"; }
public int multiplicador() { return 1; }
}
/*
MCMXXVIII = 1928
*/
Anacleto Correia 74
IPS-ESTSetúbal Padrões de Desenho
Iterator (Iterador)
Participantes:
· Iterator
o Define uma interface para acesso sequencial aos
elementos de uma estrutura ou agregado.
· ConcreteIterator
o Implementa a interface Iterator.
o Mantém registo da posição corrente durante a passagem
pelo agregado de elementos.
· Aggregate
o Define uma interface para criação do objecto Iterator.
· ConcreteAggregate
o Implementa a criação da interface Iterator para retornar
uma instância de ConcreteIterator.
Anacleto Correia 75
IPS-ESTSetúbal Padrões de Desenho
Exemplo
// Padrão Iterator
// Iterator
interface Iterator {
boolean hasNext();
Object next();
}
// Agregate
interface Pilha {
//Métodos selectores
public int tamanho();
//Métodos de actualização
public void empilha(Object elemento);
// ConcreteAggregate
class PilhaArray
implements Pilha {
// ConcreteIterator
private class PilhaArrayIterator
implements Iterator {
int pos = -1;
public boolean hasNext() {
return (pos < topo);
}
Anacleto Correia 76
IPS-ESTSetúbal Padrões de Desenho
//Cliente
public class PatIterator {
public static void main(String args[]) {
Iterator ai, ai2;
PilhaArray s;
s = new PilhaArray();
for (int i = 0; i < 5; i++)
s.empilha(new Integer(i));
ai = s.getIterator();
Anacleto Correia 77
IPS-ESTSetúbal Padrões de Desenho
while (ai.hasNext()) {
System.out.println("\n1 Iterador: " + ai.next());
System.out.print(" 2 Iterador:");
for (ai2 = s.getIterator(); ai2.hasNext(); )
System.out.print(" " + ai2.next());
}
}
}
/*
1 Iterador: 0
2 Iterador: 0 1 2 3 4
1 Iterador: 1
2 Iterador: 0 1 2 3 4
1 Iterador: 2
2 Iterador: 0 1 2 3 4
1 Iterador: 3
2 Iterador: 0 1 2 3 4
1 Iterador: 4
2 Iterador: 0 1 2 3 4
*/
Anacleto Correia 78
IPS-ESTSetúbal Padrões de Desenho
Mediator (Mediador)
Participantes:
· Mediator
o Define uma interface para comunicação com objectos
Colleague
· ConcreteMediator
o Implementa comportamento cooperativo coordenando
objectos Colleague
o Conhece e mantém os objectos ConcreteColleague
· ConcreteColleague
o Cada classe ConcreteColleague conhece o seu objecto
Mediator
o Cada colega comunica com o mediator, quando de outra
forma comunicaria com outro objecto ConcreteColleague
Anacleto Correia 79
IPS-ESTSetúbal Padrões de Desenho
Exemplo
// Padrão Mediator
import java.util.HashMap;
// Aplicação Cliente
public class PatMediator {
public static void main(String[] args) {
// Criação de sala de conversação
SalaConversacao salaConversacao = new SalaConversacao();
salaConversacao.registar(George);
salaConversacao.registar(Paul);
salaConversacao.registar(Ringo);
salaConversacao.registar(John);
salaConversacao.registar(Yoko);
// participantes na conversa
Yoko.enviar("John", "Hi John!");
Paul.enviar("Ringo", "All you need is love");
Ringo.enviar("George", "My sweet Lord");
Paul.enviar("John", "Can't buy me love");
John.enviar("Yoko", "My sweet love");
}
}
// "Mediator"
abstract class AbstractChatroom {
public abstract void registar(Participante participante);
public abstract void enviar(
String de, String para, String mensagem);
}
// "ConcreteMediator"
class SalaConversacao
extends AbstractChatroom {
private HashMap participantes = new HashMap();
Anacleto Correia 80
IPS-ESTSetúbal Padrões de Desenho
participante.setSala(this);
}
// "AbstractColleague"
class Participante {
private SalaConversacao salaConversacao;
private String nome;
// Construtor
public Participante(String nome) {
this.nome = nome;
}
// Propriedades
public String getNome() {
return nome;
}
//" ConcreteColleague1"
class Beatle
extends Participante {
// Construtor
public Beatle(String nome) {
super(nome);
}
//" ConcreteColleague2"
class NaoBeatle
extends Participante {
// Construtor
public NaoBeatle(String nome) {
super(nome);
}
Anacleto Correia 81
IPS-ESTSetúbal Padrões de Desenho
}
}
/*
Para um Beatle: Yoko a John: 'Hi John!'
Para um Beatle: Paul a Ringo: 'All you need is love'
Para um Beatle: Ringo a George: 'My sweet Lord'
Para um Beatle: Paul a John: 'Can't buy me love'
Para um não-Beatle: John a Yoko: 'My sweet love'
*/
Anacleto Correia 82
IPS-ESTSetúbal Padrões de Desenho
Memento (Memória)
Participantes:
· Memento
o Armazena o estado interno do objecto Originator. O
Memento pode armazenar mais ou menos do conteúdo do
estado interno de Originator, em função do critério deste.
o Protege contra o acesso de outros objectos que não o
Originator. Memento tem de facto duas interfaces.
Caretaker vê a interface mais estreita de Memento –
apenas pode passar o Memento para outros objectos.
Originator, pelo contrário, vê uma interface mais
alargada, que lhe permite acesso a todos os dados
necessários para se restaurar o seu estado prévio.
Idealmente, apenas ao Originator, que produz o
Memento, será permitido o acesso ao estado interno
deste.
· Originator
o Cria um Memento contendo um snapshot do seu estado
corrente.
o Utiliza o Memento para restaurar o seu estado interno.
· Caretaker
o É responsável pela salvaguarda de Memento.
o Nunca opera sobre ou examina o conteúdo de Memento.
Anacleto Correia 83
IPS-ESTSetúbal Padrões de Desenho
Este padrão é comum nas situações em que por exemplo se faz uma
auto-reparação. Imagine-se a reparação dos travões de cilindro, de
numa viatura. Os cilindros são removidos de ambos os lados,
expondo os travões do lado direito e esquerdo. Só se desmonta um
dos lados, enquanto o outro serve de auxiliar de memória (Memento)
da forma como o travão deve ficar montados. Só após um dos lados
ter sido reparado, é que o outro é desmontado. O travão reparado
será então Memento do segundo a ser reparado.
Exemplo
// padrão Memento
// Cliente
public class PatMemento {
public static void main(String[] args) {
PrevisaoVendas s = new PrevisaoVendas();
s.setNome("João Pedro");
s.setTelefone ("21-5630990");
s.setOrcamento(25000.0);
Anacleto Correia 84
IPS-ESTSetúbal Padrões de Desenho
}
}
// "Originator"
class PrevisaoVendas {
private String nome;
private String telefone;
private double orcamento;
// Propriedades
public String getNome() {
return nome;
}
public void setNome(String valor) {
nome = valor;
System.out.println("Nome: " + nome);
}
// "Memento"
class Memento {
private String nome;
private String telefone;
private double orcamento;
// Construtor
public Memento(String nome, String telefone, double orcamento)
{
Anacleto Correia 85
IPS-ESTSetúbal Padrões de Desenho
this.nome = nome;
this.telefone = telefone;
this.orcamento = orcamento;
}
// Propriedades
public String getNome() {
return nome;
}
public void setNome(String valor) {
nome = valor;
}
// "Caretaker"
class ArmazenaMemoria
{
private Memento memento;
// Propriedade
public Memento getMemento() {
return memento;
}
public void setMemento(Memento valor) {
memento = valor;
}
}
/*
Nome: João Pedro
Telefone: 21-5630990
Orcamento: 25000.0
Guardar estado --
Recuperar estado --
Anacleto Correia 86
IPS-ESTSetúbal Padrões de Desenho
Observer (Observador)
Participantes:
· Subject
o Conhece os seus observadores. Qualquer número de
objectos Observer pode observar um Subject.
o Fornece uma interface para adicionar e remover objectos
Observer.
· ConcreteSubject
o Armazena os estados que interessam ao
ConcreteObserver.
o Envia uma notificação aos Observers, quando o estado se
altera.
· Observer
o Define uma interface de alteração, para os objectos que
devam ser notificados de alterações verificados no
Subject.
Anacleto Correia 87
IPS-ESTSetúbal Padrões de Desenho
· ConcreteObserver
o Mantém uma referência para o objecto ConcreteSubject.
o Armazena o estado consistente com o de Subject.
o Implementa a interface de actualização definida em
Observer, para que o seu estado seja consistente com o
de Subject.
Anacleto Correia 88
IPS-ESTSetúbal Padrões de Desenho
Exemplo
// Padrão Observer
// Definir dependências entre objectos do tipo um-para-muitos.
// Quando o objecto altera o seu estado, todos os objectos
// dependentes são notificados para poderem agir em conformidade.
// Subject
import java.util.Observable;
// Observer
import java.util.Observer;
class Flor {
private boolean estaAberto;
private NotificadorAbertura notificaAbertura = new NotificadorAbertura();
private NotificadorFecho notificaFecho = new NotificadorFecho();
public Flor() {
estaAberto = false;
}
// ConcreteSubject
private class NotificadorAbertura
extends Observable {
private boolean jaAberto = false;
public void notifyObservers() {
if (estaAberto && !jaAberto) {
setChanged();
super.notifyObservers();
jaAberto = true;
}
}
// ConcreteSubject
private class NotificadorFecho
extends Observable {
private boolean jaFechado = false;
public void notifyObservers() {
if (!estaAberto && !jaFechado) {
setChanged();
super.notifyObservers();
jaFechado = true;
}
}
Anacleto Correia 89
IPS-ESTSetúbal Padrões de Desenho
class Abelha {
private String nome;
private ObservadorAbertura abreObsrv = new ObservadorAbertura();
private ObservadorFecho fechaObsrv = new ObservadorFecho();
public Abelha(String nm) {
nome = nm;
}
// ConcreteObserver
private class ObservadorAbertura
implements Observer { // observa aberturas
public void update(Observable ob, Object a) {
System.out.println("Abelha " + nome + ": hora do pequeno-almoço!");
}
}
// ConcreteObserver
private class ObservadorFecho
implements Observer { // observa fechos
public void update(Observable ob, Object a) {
System.out.println("Abelha " + nome + ": hora de deitar!");
}
}
class BeijaFlor {
private String nome;
private ObservadorAbertura abreObsrv = new ObservadorAbertura();
private ObservadorFecho fechaObsrv = new ObservadorFecho();
public BeijaFlor(String nm) {
nome = nm;
}
// ConcreteObserver
private class ObservadorAbertura
implements Observer { // obs abertu
public void update(Observable ob, Object a) {
System.out.println("BeijaFlor " + nome + ": hora do pequeno-almoço!");
}
}
// ConcreteObserver
private class ObservadorFecho
implements Observer { // observa fechos
public void update(Observable ob, Object a) {
System.out.println("BeijaFlor " + nome + ": hora de deitar!");
}
}
// Cliente
public class ObserverPattern {
public static void main(String args[]) {
Flor f = new Flor(); // objecto Observado
Abelha aA = new Abelha("A"); // objecto Observador
Abelha aB = new Abelha("B"); // objecto Observador
BeijaFlor bA = new BeijaFlor("A"); // objecto Observador
BeijaFlor bB = new BeijaFlor("B"); // objecto Observador
Anacleto Correia 90
IPS-ESTSetúbal Padrões de Desenho
f.notificadorAbertura().addObserver(bB.observadorAbertura());
f.notificadorAbertura().addObserver(aA.observadorAbertura());
f.notificadorAbertura().addObserver(aB.observadorAbertura());
f.notificadorFecho().addObserver(bA.observadorFecho());
f.notificadorFecho().addObserver(bB.observadorFecho());
f.notificadorFecho().addObserver(aA.observadorFecho());
f.notificadorFecho().addObserver(aB.observadorFecho());
Anacleto Correia 91
IPS-ESTSetúbal Padrões de Desenho
State (Estado)
Participantes:
· Context
o Define uma interface para os clientes.
o Mantém uma instância de uma subclasse ConcreteState
que define o estado actual.
· State
o Define uma interface para encapsular o comportamento
associado a um estado particular de Context.
· Concrete State
o Cada subclasse implementa o comportamento associado a
um estado particular de Context.
Anacleto Correia 92
IPS-ESTSetúbal Padrões de Desenho
Anacleto Correia 93
IPS-ESTSetúbal Padrões de Desenho
Exemplo
// Padrão State
// Aplicação Cliente
public class PatState {
public static void main(String[] args) {
// Abrir nova Conta
Conta conta = new Conta("Jim Johnson");
// "State"
abstract class Estado {
protected Conta conta;
protected double saldo;
// Propriedades
public Conta getConta() {
return conta;
}
// "ConcreteState"
// Conta a descoberto
class EstadoVermelho
extends Estado {
double taxaServico;
// Construtor
public EstadoVermelho(Estado estado) {
this.saldo = estado.getSaldo();
this.conta = estado.getConta();
inicializar();
}
Anacleto Correia 94
IPS-ESTSetúbal Padrões de Desenho
verificarAlteracaoEstado();
}
// "ConcreteState"
// Silver é um estado em que não há juros de depósito
class EstadoPrata
extends Estado {
// construtores sobrecarregados
public EstadoPrata(Estado estado) {
this(estado.getSaldo(), estado.getConta());
}
// "ConcreteState"
// Estado em que há juro de depósitos
class EstadoOuro
extends Estado {
// construtores sobrecarregados
public EstadoOuro(Estado estado) {
this(estado.getSaldo(), estado.getConta());
}
Anacleto Correia 95
IPS-ESTSetúbal Padrões de Desenho
this.conta = conta;
inicializar();
}
// "Context"
class Conta {
private Estado estado;
private String owner;
// Construtor
public Conta(String owner) {
// As novas contas são por omissão 'Silver'
this.owner = owner;
estado = new EstadoPrata(0.0, this);
}
// Propriedades
public double getSaldo() {
return estado.getSaldo();
}
Anacleto Correia 96
IPS-ESTSetúbal Padrões de Desenho
Anacleto Correia 97
IPS-ESTSetúbal Padrões de Desenho
Strategy (Estratégia)
Participantes:
· Strategy
o Declara uma interface comum a todos os algoritmos
suportados. Context utiliza esta interface para evocar o
algoritmo definido por um ConcreteStrategy
· ConcreteStrategy
o Implementa o algoritmo utilizando a interface Strategy.
· Context
o É configurado com um objecto ConcreteStrategy.
o Mantém uma referência para um objecto Strategy.
o Pode definir uma interface para permitir o acesso de
Strategy aos seus dados.
Anacleto Correia 98
IPS-ESTSetúbal Padrões de Desenho
Exemplo
// Padrão Strategy
// Strategy
interface Preco {
double algoritmo(double p);
}
// As diferentes estratégias
class PrecoPublico implements Preco {
public double algoritmo(double p) {
return p;
}
}
class PrecoCredito implements Preco {
public double algoritmo(double p) {
return (p*1.2);
}
}
class PrecoVip implements Preco {
public double algoritmo(double p) {
return (p*0.8);
}
}
// O "Context" controla a estratégia
class DeterminaPreco {
private Preco politicaPreco;
public DeterminaPreco(Preco estrat) {
politicaPreco = estrat;
}
double precoAplicavel(double p) {
return politicaPreco.algoritmo(p);
}
void trocaAlgoritmo(Preco novoAlgoritmo) {
politicaPreco = novoAlgoritmo;
Anacleto Correia 99
IPS-ESTSetúbal Padrões de Desenho
}
}
// A classe Cliente
public class testaPadrao {
static DeterminaPreco dt =new DeterminaPreco(new
PrecoPublico());
static double preco = 40.0;
public static void print(double p) {
System.out.println(p);
}
public static void main(String args[]) {
print(dt.precoAplicavel(preco));
dt.trocaAlgoritmo(new PrecoVip());
print(dt.precoAplicavel(preco));
}
}
/*
40.0
32.0
*/
Participantes:
· AbstractClass
o Define métodos abstractos, que as subclasses concretas
irão definir, para implementar passos concretos do
algoritmo.
o Implementa um método-padrão, que define o esqueleto
de um algoritmo. O método-padrão evoca os métodos
abstractos ou outros métodos definidos na classe
AbstractClass, ou métodos definidos noutros objectos.
· ConcreteClass
o Implementa os métodos abstractos definidos na classe
AbstractClass, de forma que a subclasse possa realizar
passos especializados do algoritmo.
Exemplo
// Olá Mundo!
// Olá Mundo!
// Olá Mundo!
// Olá Mundo!
// Olá Mundo!
Visitor (Visitante)
Participantes:
· Visitor
o Declara o método visit para cada classe de
ConcreteElement na estrutura de objectos. O nome do
método e a assinatura, identificam a classe que envia o
pedido visit ao Visitor Isso permite ao visitor determinar a
classe concreta do elemento a ser visitado. Então o visitor
pode aceder directamente aos elementos, através da sua
interface particular.
· ConcreteVisitor
o Implementa os métodos declarados pelo Visitor. Cada
método implementa um fragmento do algoritmo definido
para a correspondente classe ou objecto na estrutura.
ConcreteVisitor fornece o contexto para o algoritmo e
armazena o seu estado local. Este estado, geralmente
acumula resultados durante a passagem pelos elementos
da estrutura.
· Element
o Define o método Accept que recebe um visitor como
argumento.
· ConcreteElement
o Implementa o método Accept que recebe um visitor como
argumento.
· ObjectStructure
o Pode enumerar os seus elementos
Exemplo
// Padrão Visitor
import java.util.ArrayList;
// Aplicação Cliente
public class PatVisitor {
public static void main(String[] args) {
// Carregamento de uma collection de empregado
Empregados e = new Empregados();
e.adicionar(new Administrativo());
e.adicionar(new DirectorDepartamento());
e.adicionar(new DirectorGeral());
}
}
// "Visitor"
interface IVisitor {
void visitar(Elemento elemento);
}
// "ConcreteVisitor1"
class RendimentoVisitado
implements IVisitor {
public void visitar(Elemento elemento) {
Empregado empregado = (Empregado) elemento;
// "ConcreteVisitor2"
class FeriasVisitado
implements IVisitor {
public void visitar(Elemento elemento) {
Empregado empregado = (Empregado) elemento;
class Administrativo
extends Empregado {
// Constructor
public Administrativo() {
super("Pedro", 25000.0, 14);
}
}
class DirectorDepartamento
extends Empregado {
// Constructor
public DirectorDepartamento() {
super("Elias", 35000.0, 16);
}
}
class DirectorGeral
extends Empregado {
// Construtor
public DirectorGeral() {
super("Duarte", 45000.0, 21);
}
}
// "Elemento"
abstract class Elemento {
public abstract void aceitar(IVisitor visitor);
}
// "ConcreteElement"
class Empregado
extends Elemento {
String nome;
double rendimento;
int diasFerias;
// Construtor
public Empregado(String nome, double rendimento,
int diasFerias) {
this.nome = nome;
this.rendimento = rendimento;
this.diasFerias = diasFerias;
}
// Propriedades
public String getNome() {
return nome;
}
// "ObjectStructure"
class Empregados {
private ArrayList empregados = new ArrayList();
*/
Referências
http://www.jablo.com.br/page/engenho/
Patterns in C#
http://www.dofactory.com/Patterns/PatternBuilder.aspx
Patterns Home Page - http://hillside.net/
Pattern Index - http://c2.com/cgi/wiki?PatternIndex
Design Patterns in Java -http://www.fluffycat.com/java/patterns.html
Duell, Michael, Non-Software Examples of Software Design Patterns -
http://www2.ing.puc.cl/~jnavon/IIC2142/patexamples.htm