Você está na página 1de 223

Padres

de
Design
com aplicaes em Java

Helder da Rocha (helder.darocha@gmail.com)


Objetivos

Apresentar cada um dos 23 padres clssicos


(catlogo do Gang of Four) descrevendo [2][GoF]
O problema que solucionam
A soluo
Diagramas UML
Exemplos em Java
Aplicaes tpicas
Apresentar os 9 padres de atribuies de
responsabilidade (GRASP) [4][Larman]
Apresentar 2 padres emergentes
Injeo de dependncias (aplicao do GRASP Indirection)
Aspectos

2
O que um padro?

Maneira testada ou documentada de alcanar


um objetivo qualquer
Padres so comuns em vrias reas da engenharia
Design Patterns, ou Padres de Design*
Padres para alcanar objetivos na engenharia de
software usando classes e mtodos em linguagens
orientadas a objeto
Inspirado em "A Pattern Language" de Christopher
Alexander, sobre padres de arquitetura de cidades,
casas e prdios
* Ou ainda Padres de Projeto, embora algo se perca nesta traduo!!
3
Responsabilidades

Booch e Rumbaugh Responsabilidade um


contrato ou obrigao de um tipo ou classe.
Dois tipos de responsabilidades dos objetos:
De conhecimento (knowing): sobre dados privativos
e encapsulados; sobre objetos relacionados; sobre
coisas que pode calcular ou derivar.
De realizao (doing): fazer alguma coisa em si
mesmo; iniciar uma ao em outro objeto; controlar
e coordenar atividades em outros objetos.
Responsabilidades so atribudas aos objetos
durante o design
4
Responsabilidades e Mtodos

A traduo de responsabilidades em classes e mtodos


depende da granularidade da responsabilidade
Mtodos so implementados para cumprir
responsabilidades
Uma responsabilidade pode ser cumprida por um nico
mtodo ou uma coleo de mtodos trabalhando em
conjunto
Responsabilidades do tipo knowing geralmente so
inferidas a partir do modelo conceitual (so os
atributos e relacionamentos)

5
Responsabilidades e
Diagramas de Interao
Diagramas de interao mostram escolhas ao atribuir
responsabilidades a objetos
No diagrama de
colaborao ao lado
objetos Order tm
a responsabilidade
de se prepararem:
mtodo prepare()
O cumprimento dessa
responsabilidade requer
colaborao com
objetos Order Line e
Stock Item
Fonte: [4] Craig Larman, Applying UML and Patterns, 2nd. Edition 6
Padres

Padres so um repertrio de solues e princpios que


ajudam os desenvolvedores a criar software e que so
codificados em um formato estruturado consistindo de
Nome
Problema que soluciona
Soluo do problema
O objetivo dos padres codificar conhecimento
(knowing) existente de uma forma que possa ser
reaplicado em contextos diferentes

7
Padres GRASP
Introduzidos por Craig Larman em seu livro Applying
UML and Patterns [4]
GRASP: General Responsibility and Assignment
Software Patterns
Os padres GRASP descrevem os princpios fundamentais da
atribuio de responsabilidades a objetos, expressas na
forma de padres
Esses padres exploram os princpios fundamentais de
sistemas OO
5 padres fundamentais
4 padres avanados
Se voc conhece os padres GRASP, pode dizer que
compreende o paradigma orientado a objetos

8
Padres clssicos ou padres GoF
O livro "Design Patterns (1994) de Erich Gamma,
John Vlissides, Ralph Jonhson e Richard Helm,
descreve 23 padres de design [2]
So solues genricas para os problemas mais comuns do
desenvolvimeto de software orientado a objetos
O livro tornou-se um clssico na literatura orientada a
objeto e continua atual
No so invenes. So documentao de solues obtidas
atravs da experincia. Foram coletados de experincias
de sucesso na indstria de software, principalmente de
projetos em C++ e SmallTalk
Os quatro autores, so conhecidos como "The Gang of
Four", ou GoF

9
Mais padres?

H vrios catlogos de padres em software


Muitos so especficos a uma determinada rea (padres
J2EE, padres de implementao em Java, em C#,
padres para concorrncia, sistemas distribudos, etc.)
Os padres apresentados aqui so aplicveis em Java e
outras linguagens
Dois outros padres sero apresentados
Dependency Injection: um caso particular de um dos
padres GRASP (Indirection) bastante popular no
momento (tambm conhecido como Inverso de Controle)
Aspectos: uma extenso ao paradigma orientado a objetos
que ajuda a lidar com limitaes dos sistemas OO

10
Por que aprender padres?
Aprender com a experincia dos outros
Identificar problemas comuns em engenharia de software e
utilizar solues testadas e bem documentadas
Utilizar solues que tm um nome: facilita a comunicao,
compreenso e documentao
Aprender a programar bem com orientao a objetos
Os 23 padres de projeto "clssicos" utilizam as melhores
prticas em OO para atingir os resultados desejados
Desenvolver software de melhor qualidade
Os padres utilizam eficientemente polimorfismo, herana,
modularidade, composio, abstrao para construir cdigo
reutilizvel, eficiente, de alta coeso e baixo acoplamento
11
Por que aprender padres?
Vocabulrio comum
Faz o sistema ficar menos complexo ao permitir que se
fale em um nvel mais alto de abstrao
Ajuda na documentao e na aprendizagem
Conhecendo os padres de projeto torna mais fcil a
compreenso de sistemas existentes
"As pessoas que esto aprendendo POO freqentemente
reclamam que os sistemas com os quais trabalham usam
herana de forma complexa e que difcil de seguir o fluxo
de controle. Geralmente a causa disto que eles no
entendem os padres do sistema" [GoF]
Aprender os padres ajudam um novato a agir mais como
um especialista
12
Elementos de um padro

Nome
Problema
Quando aplicar o padro, em que condies?
Soluo
Descrio abstrata de um problema e como usar os
elementos disponveis (classes e objetos) para solucion-lo
Conseqncias
Custos e benefcios de se aplicar o padro
Impacto na flexibilidade, extensibilidade, portabilidade e
eficincia do sistema

13
Padres GoF: Formas de classificao
H vrias formas de classificar os padres. Gamma et al
[2] os classifica de duas formas
Por propsito: (1) criao de classes e objetos, (2)
alterao da estrutura de um programa, (3) controle do
seu comportamento
Por escopo: classe ou objeto
Metsker [1] os classifica em 5 grupos, por inteno
(problema a ser solucionado): Padres GRASP focam
(1) oferecer uma interface, neste objetivo
(2) atribuir uma responsabilidade,
(3) realizar a construo de classes ou objetos
(4) controlar formas de operao
(5) implementar uma extenso para a aplicao
14
Classificao dos 23 padres segundo GoF*

Propsito
1. Criao 2. Estrutura 3. Comportamento
Escopo Classe Factory Method Class Adapter Interpreter
Template Method
Objeto Abstract Factory Object Adapter Chain of Responsibility
Builder Bridge Command
Prototype Composite Iterator
Singleton Decorator Mediator
Facade Memento
Flyweight Observer
Proxy State
Strategy
Visitor

* Padres "clssicos" selecionados e organizados por Gamma et al. "Design Patterns" [2]
15
Classificao dos padres GoF
segundo Metsker [1]
Inteno Padres

1. Interfaces Adapter, Facade, Composite, Bridge


2. Responsabilidade Singleton, Observer, Mediator, Proxy,
Chain of Responsibility, Flyweight
3. Construo Builder, Factory Method, Abstract Factory,
Prototype, Memento
4. Operaes Template Method, State, Strategy, Command,
Interpreter
5. Extenses Decorator, Iterator, Visitor

Usaremos esta classificao


16
Relacionamentos
entre os
23 padres
"clssicos"

Fonte: [2] 17
Introduo: interfaces

Interface: coleo de mtodos e dados que uma


classe permite que objetos de outras classes acessem
Implementao: cdigo dentro dos mtodos
Interface Java: componente da linguagem que
representa apenas a interface de um objeto
Exigem que classe que implementa a interface oferea
implementao para seus mtodos
No garante que mtodos tero implementao que faa
efetivamente alguma coisa (chaves vazias): stubs.

18
Alm das interfaces

Padres de design que concentram-se principalmente


na adaptao de interfaces
Adapter: para adaptar a interface de uma classe para
outra que o cliente espera
Faade: oferecer uma interface simples para uma coleo
de classes
Composite: definir uma interface comum para objetos
individuais e composies de objetos
Bridge: desacoplar uma abstrao de sua implementao
para que ambos possam variar independentemente

19
1
Adapter
"Objetivo: converter a interface de uma classe em outra
interface esperada pelos clientes. Adapter permite a
comunicao entre classes que no poderiam trabalhar
juntas devido incompatibilidade de suas interfaces." [GoF]
Problema e Soluo
Problema
Cliente
operacao() void operacao() {
metodoEsperado();
} Soluo

ClasseExistente Adaptador
metodoUtil() metodoEsperado()

void metodoEsperado() {
metodoUtil();
}

Adaptador
21
Duas formas de Adapter

Class Adapter: usa herana mltipla


interface
Cliente Alvo ClasseExistente
operacao() metodoUtil()

implementa

Adaptador
operacao() metodoUtil()

Cliente: aplicao que colabora com objetos aderentes interface Alvo


Alvo: define a interface requerida pelo Cliente
ClasseExistente: interface que requer adaptao
Adaptador (Adapter): adapta a interface do Recurso interface Alvo
22
Duas formas de Adapter

Object Adapter: usa composio


Alvo ClasseExistente
Cliente
operacao() metodoUtil()

Adaptador ClasseExistente ce
operacao() = new ClasseExistente ()
...
ce.metodoUtil()

nica soluo se Alvo no for uma interface Java


Adaptador possui referncia para objeto que ter sua interface
adaptada (instncia de ClasseExistente).
Cada mtodo de Alvo chama o(s) mtodo(s) correspondente(s)
na interface adaptada.
23
public class ClienteExemplo {
Alvo[] alvos = new Alvo[10];
Class Adapter
public void inicializaAlvos() {
alvos[0] = new AlvoExistente(); em Java
alvos[1] = new Adaptador();
// ...
}
public void executaAlvos() {
for (int i = 0; i < alvos.length; i++) {
alvo.operacao();
} public interface Alvo {
} void operacao();
} }

public class Adaptador extends ClasseExistente implements Alvo {


public void operacao() {
String texto = metodoUtilDois("Operao Realizada.");
metodoUtilUm(texto);
}
}

public class ClasseExistente {


public void metodoUtilUm(String texto) {
System.out.println(texto);
}
public String metodoUtilDois(String texto) {
return texto.toUpperCase();
}
}
24
public class ClienteExemplo {
Alvo[] alvos = new Alvo[10];
Object Adapter
public void inicializaAlvos() {
alvos[0] = new AlvoExistente(); em Java
alvos[1] = new Adaptador();
// ...
}
public void executaAlvos() {
for (int i = 0; i < alvos.length; i++) {
alvos[i].operacao();
} public abstract class Alvo {
} public abstract void operacao();
} // ... resto da classe
}

public class Adaptador extends Alvo {


ClasseExistente existente = new ClasseExistente();
public void operacao() {
String texto = existente.metodoUtilDois("Operao Realizada.");
existente.metodoUtilUm(texto);
}
}
public class ClasseExistente {
public void metodoUtilUm(String texto) {
System.out.println(texto);
}
public String metodoUtilDois(String texto) {
return texto.toUpperCase();
}
}
25
Quando usar?

Sempre que for necessrio adaptar uma


interface para um cliente
Class Adapter
Quando houver uma interface que permita a
implementao esttica
Object Adapter
Quando menor acoplamento for desejado
Quando o cliente no usa uma interface Java ou
classe abstrata que possa ser estendida
26
Onde esto os adapters?

A API do J2SDK tem vrios adapters


Voc consegue identific-los?

27
2
Faade

"Oferecer uma interface nica para um conjunto de interfaces


de um subsistema. Faade define uma interface de nvel mais
elevado que torna o subsistema mais fcil de usar." [GoF]

28
Cliente precisa saber Problema
muitos detalhes do
subsistema para Cliente
utiliz-lo!

Subsistema

29
Estrutura de Faade
Cliente
Crie uma fachada!
Subsistema

Faade Delega requisies aos objetos


apropriados para cada tarefa

30
Aplicao
f:Faade
Faade Exemplo
banco:BancoDeDados
operacao()
registrar()
comprar()
fecharCompra(id)
f.registrar("Z", 123);
f.comprar(223, 123);
f.comprar(342, 123); Cliente c =
f.fecharCompra(123); banco.selectCliente(id);
double valor =
c.getCarrinho.getTotal();
banco.processarPagamento(c, valor);
Carrinho
create():Carrinho
adicionar(Produto p)
getTotal():double
BancoDeDados
selectCliente(id)
selectProduto(id):Produto
Cliente processarPagamento()
create(nome,id):Cliente
adicionarCarrinho(Carrinho c)
getCarrinho():Carrinho InterfaceDeDados

Produto
create(nome, id,preco):Produto
getPreco():double
31
Faade em Java public class Facade {
BancoDeDados banco = Sistema.obterBanco();
public void registrar(String nome, int id) {
Cliente c = Cliente.create(nome, id);
class Aplicao { Carrinho c = Carrinho.create();
... c.adicionarCarrinho();
Facade f; }
// Obtem instancia f public void comprar(int prodID, int clienteID) {
f.registrar("Z", 123); Cliente c = banco.selectCliente(cliente ID);
f.comprar(223, 123); Produto p = banco.selectProduto(prodID) {
f.comprar(342, 123); c.getCarrinho().adicionar(p);
}
f.fecharCompra(123); public void fecharCompra(int clienteID) {
... Cliente c = banco.selectCliente(clienteID);
double valor = c.getCarrinho.getTotal();
} banco.processarPagamento(c, valor);
}
}

public class Carrinho { public class Produto {


static Carrinho create() {...} static Produto create(String nome,
void adicionar(Produto p) {...} int id,double preco) {...}
double getTotal() {...} double getPreco() {...}
} }

public class Cliente { public class BancoDeDados {


static Cliente create(String nome, Cliente selectCliente(int id) {...}
int id) {...} Produto selectProduto(int id) {...}
void adicionarCarrinho(Carrinho c) {...} void processarPagamento() {...}
Carrinho getCarrinho() {...} }
} 32
Quando usar?
Sempre que for desejvel criar uma interface para
um conjunto de objetos com o objetivo de facilitar o
uso da aplicao
Permite que objetos individuais cuidem de uma nica
tarefa, deixando que a fachada se encarregue de divulgar
as suas operaes
Fachadas viabilizam a separao em camadas com
alto grau de desacoplamento
Existem em vrias partes da aplicao
Fachada da aplicao para interface do usurio
Fachada para sistema de persistncia: Data Access Object

33
Nvel de acoplamento
Fachadas podem oferecer maior ou menor isolamento
entre aplicao cliente e objetos
Nvel ideal deve ser determinado pelo nvel de acoplamento
desejado entre os sistemas
A fachada mostrada como exemplo isola totalmente o
cliente dos objetos
Facade f; // Obtem instancia f
f.registrar("Z", 123);

Outra verso com menor isolamento (requer que


aplicao-cliente conhea objeto Cliente)
Cliente joao = Cliente.create("Joo", 15);
f.registrar(joao); // mtodo registrar(Cliente c)
34
Questes

Voc conhece algum exemplo de na API do


J2SDK
Onde voc criaria fachadas em uma aplicao
Web J2EE?
Voc saberia dizer qual a diferena entre
Faade e Adapter

35
3
Composite

"Compor objetos em estruturas de rvore para representar


hierarquias todo-parte. Composite permite que clientes
tratem objetos individuais e composies de objetos de
maneira uniforme." [GoF]
Problema
Cliente precisa tratar de maneira uniforme
objetos individuais e composies desses objetos

Cliente

Rede

Rede

37
Tratar grupos e indivduos Soluo
diferentes atravs de uma
nica interface

Cliente

Todo mundo
* componente!
Componente

* Individuo
Individuo Grupo

38
Estrutura de Composite
:Composicao

:Composicao :Folha :Folha

:Folha :Folha :Folha

Componente
Cliente
operacao() 1..*

filhos
Folha Composicao
operacao() operacao() for (int i=0; i<filhos.length; i++) {
add(Componente) filho = filhos[i];
remove(Componente) filho.operacao();
}
getFilho(int)
39
Composite em Java
import java.util.*;
public class MachineComposite extends MachineComponent {
protected List components = new ArrayList();
public void add(MachineComponent component) {
components.add(component);
}
public int getMachineCount() {
// Exerccio
} public abstract class MachineComponent {
} public abstract int getMachineCount();
public String getName() {
return name;
O que colocar no lugar }
indicado para implementar
public void setName(String name) {
this.name = name;
corretamente esta classe? }
}
public abstract class Machine extends MachineComponent {
public int getMachineCount() {
// Exerccio
} Fonte: [2]
}
40
Quando usar?

Sempre que houver necessidade de tratar um


conjunto como um indivduo
Funciona melhor se relacionamentos entre os
objetos for uma rvore
Caso o relacionamento contenha ciclos, preciso
tomar precaues adicionais para evitar loops
infinitos, j que Composite depende de
implementaes recursivas
H vrias estratgias de implementao
41
Questes
Cite exemplos de Composite
Na API do J2SDK
Em frameworks que voc conhece
Em aplicaes que voc conhece
Como poderia ser resolvido o problema abaixo?
preciso saber quantas pessoas iro participar do
congresso
Participantes podem ser pessoas ou instituio
Indivduo
getAssento()
Congresso
totalParticipantes()
totalAssentos()
Instituio
getMembros()
42
4
Bridge

"Desacoplar uma abstrao de sua implementao para que


os dois possam variar independentemente." [GoF]
Problema (1)

Necessidade de um driver
Exemplo: implementaes especficas para tratar
objeto em diferentes meios persistentes

Publicao
getTitulo()
getAutor(id)

PublicaoImplXML PublicaoImplBD
getTitulo() getTitulo()
getAutor(id) getAutor(id)

44
Problema (II)

Mas herana complica a implementao


Publicao
getTitulo()
getAutor(id)

Livro Revista
getISBN() getArtigo()

LivroImplXML LivroImplBD RevistaImplXML RevistaImplBD


getTitulo() getTitulo() getTitulo() getTitulo()
getAutor(id) getAutor(id) getAutor(id) getAutor(id)
getISBN() getISBN() getArtigo() getArtigo()

45
imp.getDados(this)
Soluo: usar Bridge

Publicao
interface
imp:Implementador
Cliente Implementador
obterDados(tipo) getDados(tipo)
getTitulo()
getAutor(id)

PublicacaoImplBD
getDados(tipo)
Livro Revista
getISBN() getArtigo()
getTitulo() getTitulo()
getAutor() getAutor(id)
PublicacaoImplXML
getDados(tipo)

tipo.setTitulo("...");
tipo.setAutores(...);
tipo.setOutros(...);

46
Estrutura de Bridge

Abstrao interface
Cliente Implementador
imp:Implementador
implOperao()
operao()

ImplConcretaUm

RefinamentoDaAbstrao ImplConcretaDois

...
imp.implOperao()

A Abstrao define operaes de nivel A interface Implementador


mais elevado baseadas nas operaes define operaes primitivas
primitivas do Implementador
47
Quando usar?

Quando for necessrio evitar uma ligao


permanente entre a interface e implementao
Quando alteraes na implementao no puderem
afetar clientes
Quando tanto abstraes como implementaes
precisarem ser capazes de suportar extenso atravs
de herana
Quando implementaes so compartilhadas entre
objetos desconhecidos do cliente

48
Questes

Voc conhece alguma implementao de


Bridge na API do J2SDK?

49
Resumo: quando usar?

Adapter
Adaptar uma interface existente para um cliente
Bridge
Implementar um design que permita total
desacoplamento entre interface e implementao
Faade
Simplificar o uso de uma coleo de objetos
Composite
Tratar composies e unidades uniformemente
50
Distribuio de responsabilidades
Os padres a seguir esto principalmente associados a
atribuies especiais de responsabilidade
Singleton: centraliza a responsabilidade em uma nica
instncia de uma classe
Observer: desacopla um objeto do conhecimento de que
outros objetos dependem dele
Mediator: centraliza a responsabilidade em uma classe que
determina como outros objetos interagem
Proxy: assume a responsabilidade de outro objeto (intercepta)
Chain of Responsibility: permite que uma requisio passe por
uma corrente de objetos at encontrar um que a processe
Flyweight: centraliza a responsabilidade em objetos
compartilhados de alta granularidade (blocos de montagem)
51
5
Singleton

"Garantir que uma classe s tenha uma nica instncia, e


prover um ponto de acesso global a ela." [GoF]

52
Problema

Garantir que apenas um objeto exista, independente


do nmero de requisies que receber para cri-lo
Aplicaes
Um nico banco de dados
Um nico acesso ao arquivo de log
Um nico objeto que representa um vdeo
Uma nica fachada (Faade pattern)
Objetivo: garantir que uma classe s tenha uma
instncia

53
Estrutura de Singleton

Objeto com acesso privativo


Construtor privativo (nem
subclasses tm acesso)
Singleton
-dados Ponto de acesso simples,
-instancia: null
esttico e global
-Singleton()
+getInstancia() public static Singleton getInstancia() {
if (instancia == null) {
+operacao() instancia = new Singleton();
+getDados() }
return instancia;
}

Lazy initialization idiom


Bloco deve ser synchronized* para evitar
que dois objetos tentem criar o
objeto ao mesmo tempo
(* omitido por falta de espao!) 54
Singleton em Java

public class Highlander { Esta classe


private Highlander() {} implementa o
private static Highlander instancia = new Highlander(); design pattern
public static synchronized Highlander obterInstancia() { Singleton
return instancia;
}
}

public class Fabrica {


public static void main(String[] args) {
Highlander h1, h2, h3;
//h1 = new Highlander(); // nao compila!
h2 = Highlander.obterInstancia();
h3 = Highlander.obterInstancia();
Esta classe if (h2 == h3) {
cria apenas System.out.println("h2 e h3 so mesmo objeto!");
um objeto }
Highlander }
}

55
Prs e contras
Vantagens
Acesso central e extensvel a recursos e objetos
Desvantagens
Qualidade da implementao depende da linguagem
Difcil de testar (simulaes dependem de instncia extra)
Uso (abuso) como substituto para variveis globais
Inicializao lazy "preguiosa" complicada em ambiente
multithreaded ( um anti-pattern veja a seguir)
Difcil ou impossvel de implementar em ambiente
distribudo ( preciso garantir que cpias serializadas
refiram-se ao mesmo objeto)

56
Double-checked lazy Singleton anti-pattern:
No use!
[5] [6]

Esse famoso padro um truque para suportar inicializao


lazy evitando o overhead da sincronizao
Parece uma soluo inteligente (evita sincronizao no acesso)
Mas no funciona! Inicializao de resource (null) e instanciamento
podem ser reordenados no cache
class SomeClass {
private static Resource resource = null;
public static Resource getResource() {
if (resource == null) {
synchronized (Resource.class) {
if (resource == null)
resource = new Resource();
}
}

}
}
return resource;
0
57
Alternativas
No usar lazy instantiation
Melhor alternativa (deixar otimizaes para depois)
private static final Resource resource = new Resource();
public static Resource getResource() {
return resource; &
}
Instanciamento lazy corretamente sincronizado
H custo de sincronizao em cada chamada
private static Resource resource = null;
public static synchronized Resource getResource() {
if (resource == null)
resource = new Resource();
return resource;
&
Esta tcnica explora a
} garantia de que uma
classe no
Initialize-on-demand holder class idiom inicializada antes que
private static class ResourceHolder { seja usada.
static final Resource resource = new Resource();
}

&
public static Resource getResource() {
return ResourceHolder.resource;
} Fonte: [5] 58
Questes

Cite aplicaes onde seria interessante usar


um singleton?
Questes extremas
Todos os objetos deveriam ser Singletons?
Singletons so maus e no deviam ser usados?

59
6
Observer

"Definir uma dependncia um-para-muitos entre objetos


para que quando um objeto mudar de estado, todos os seus
dependentes sejam notificados e atualizados
automaticamente." [GoF]
60
Observador 1 Observador 2

x
a
60
b
30
c
10
Problema
y 50 30 20
z 80 10 10
c b a

registra-se
Observador 1 Observador 2

a b c
a = 50% x 60 30 10
b = 30% y 50 30 20
c = 20% z 80 10 10
1 c b a

Observador 1 Observador 2

a b c
a = 20% x 60 30 10
b = 60% y 20 60 20
c = 20% z 80 10 10
2 c b a

notifica

a = 20%
b = 60%
c = 20%
3
61
Problema (2)

Como garantir que objetos que dependem de outro


objeto fiquem em dia com mudanas naquele objeto?
Como fazer com que os observadores tomem
conhecimento do objeto de interesse?
Como fazer com que o objeto de interesse atualize os
observadores quando seu estado mudar?
Possveis riscos
Relacionamento (bidirecional) implica alto acoplamento.
Como podemos eliminar o relacionamento bidirecional?
Cadastra-se
Observador Sujeito
Notifica

62
for (int i = 0; i < observadores.length; i++) {
observador = observadores[i];
Estrutura de
}
observador.atualizar();
Observer
Sujeito
observadores:Observador[] interface

cadastrar(Observador) Observador
1..*
remover(Observador) atualizar()
notificar()

importantes para eliminar o


relacionamento bidirecional

SujeitoConcreto ObservadorConcreto
-dadosDoSujeito concreto:SujeitoConcreto
dadosObservados
+setDados()
+getDados() atualizar()

dadosObservados =
return dadosDoSujeito; concreto.getDados();

63
Seqncia de Observer
cliente a:ObservadorConcreto :SujeitoConcreto

cadastrar(this)

create
b:ObservadorConcreto

cadastrar(b)

... ... ... ...


setDados(dados)

notificar()

atualizar()

atualizar()

getDados()
getDados()

64
public class ConcreteObserver
implements Observer { Observer em Java
public void update(Observable o) {
ObservableData data = (ObservableData) o;
data.getData();
}
} public class ObservableData
extends Observable {
private Object myData;
public class Observable {
public void setData(Object myData) {
List observers = new ArrayList();
this.myData = myData;
notify();
public void add(Observer o) {
}
observers.add(o);
} public Object getData() {
return myData();
public void remove(Observer o) {
}
observers.remove(o);
}
}

public void notify() {


Iterator it = observers.iterator();
while(it.hasNext()) {
Observer o = (Observer)it.next();
o.update(this); public interface Observer {
} public void update(Observable o);
} }
}
65
Seqncia de registro das ligaes
Veja cdigo de exemplo
:Cliente (baixe do site)

create
:Model
Model()

create
:View
View(model)

addListener(this)

create
:Controller
Controller(model, view)

addListener(this)

66
Seqncia de operao
Usurio aperta
boto "Ao"

:Model :View :Controller

notificar()
processar()

setEstado(s)
notificar()

processar()
atualizar()

getEstado()

67
Questes

Cite exemplos de implementaes de


Observer e MVC
Na API Java
Em frameworks que voc conhece

68
7
Mediator
"Definir um objeto que encapsula como um conjunto de
objetos interagem. Mediator promove acoplamento fraco ao
manter objetos que no se referem um ao outro
explicitamente, permitindo variar sua interao
independentemente." [GoF]

69
Problema

Como permitir que um grupo de objetos se comunique


entre si sem que haja acoplamento entre eles?
Como remover o forte acoplamento presente em
relacionamentos muitos para muitos?
Como permitir que novos participantes sejam ligados ao
grupo facilmente?

Colaborador 1 Colaborador 2

Colaborador 3

70
Soluo

Introduzir um mediador
Objetos podem se comunicar sem se conhecer

Colaborador 1 Mediador Colaborador 2

Colaborador 3

71
Estrutura de Mediator mediador.operacaoMediada();

Colaborador
Mediador
mediador:Mediador
operacaoMediada()
chamarOperacao()

ColaboradorUm
operacaoUm()
MediadorConcreto
um:SujeitoUm
dois:SujeitoDois ColaboradorDois
operacaoMediada() operacaoDois()

...
um.operacaoUm()
...
dois.operacaoDois()
...

72
Descrio da soluo

Um objeto Mediador deve encapsular toda a


comunicao entre um grupo de objetos
Cada objeto participante conhece o mediador mas ignora
a existncia dos outros objetos
O mediador conhece cada um dos objetos participantes
A interface do Mediador usada pelos colaboradores
para iniciar a comunicao e receber notificaes
O mediador recebe requisies dos remetentes
O mediador repassa as requisies aos destinatrios
Toda a poltica de comunicao determinada pelo
mediador (geralmente atravs de uma implementao
concreta do mediador)
73
Questes

Onde voc usaria mediadores?


Voc conhece exemplos de mediadores na API
Java? Em frameworks?

74
8
Proxy
"Prover um substituto ou ponto atravs do qual um objeto
possa controlar o acesso a outro." [GoF]

75
Problema
Sistema quer utilizar objeto real...
pergunta("Vou a guerra?")
Creso Deus Apolo

Mas ele no est disponvel (remoto, inaccessvel, ...)


Creso ?

Soluo: arranjar um intermedirio que saiba se


comunicar com ele eficientemente
pagamento()
Creso Orculo de Delfos
pergunta("Vou a guerra?")
pergunta("Vou a guerra?")

Mesma interface! Deus Apolo

76
interface
Cliente
Sujeito
proxy:Sujeito = new Intermediario() operacao()
executar() ...

proxy.operacao()

Intermediario
SujeitoReal
real.SujeitoReal
operacao()

Estrutura
operacao()
...
...

de Proxy real.operacao()

Cliente usa intermedirio em vez de sujeito real


Intermedirio suporta a mesma interface que sujeito real
Intermedirio contm uma referncia para o sujeito real e
repassa chamadas, possivelmente, acrescentando informaes
ou filtrando dados no processo
77
Proxy em Java
public class Creso {
...
Sujeito apolo = Fabrica.getSujeito();
apolo.operacao();
...
} inaccessvel
pelo cliente
public class SujeitoReal implements Sujeito {
public Object operacao() {
return coisaUtil;
}
}

public class Intermediario implements Sujeito {


private SujeitoReal real; cliente comunica-se
public Object operacao() { com este objeto
cobraTaxa();
return real.operacao();
}
}

public interface Sujeito {


public Object operacao();
}
78
Quando usar?
A aplicao mais comum em objetos distribudos
Exemplo: RMI (e EJB)
O Stub proxy do cliente para o objeto remoto
O Skeleton parte do proxy: cliente remoto chamado pelo Stub
RemoteInterface
toUpper(String):String

Cliente
operacao()
ObjetoRemoto
toUpper(String):String
stub.toUpper("a")

Stub rede Skeleton


toUpper(String):String servico()
socket ...

Outras aplicaes tpicas


Image proxy: guarda o lugar de imagem sendo carregada
79
Questes

Cite exemplos do uso de Proxy


Em frameworks
Na API Java
Qual a diferena entre um Proxy e um
Adapter?
Qual a diferena entre um Faade e um Proxy?
E entre um Adapter e um Faade?

80
9
Chain of
Responsibility
"Evita acoplar o remetente de uma requisio ao seu
destinatrio ao dar a mais de um objeto a chance de servir
a requisio. Compe os objetos em cascata e passa a
requisio pela corrente at que um objeto a sirva." [GoF]

81
1 10 Problema
5 Permitir que vrios objetos possam
50
servir a uma requisio ou repass-la
Permitir diviso de responsabilidades
de forma transparente

receber() R$ 1,00

receber() R$ 0,50
Um objeto pode ser uma folha Total
ou uma composio de outros receber() R$ 0,10
objetos
receber() R$ 0,05

82
Estrutura de Chain of Responsibility
sucessor
interface

Cliente Processador :Cliente


processarRequisicao()

:Processador

:Processador
ProcessadorConcretoUm
sucessor:Processador
processarRequisicao() :Processador

ProcessadorConcretoDois
sucessor:Processador
processarRequisicao()
...
sucessor.processarRequisicao() ProcessadorConcretoN
processarRequisicao()

83
Chain of Responsibility em Java
public class cliente {
...
Processador p1 = ...
Object resultado = p1.processarRequisicao();
...
}

public class ProcessadorUm implements Processador {


private Processador sucessor; Nesta estratgia
public Object processarRequisicao() { cada participante
... // codigo um
return sucessor.processarRequisicao(); conhece seu
} sucessor
}
...

public class ProcessadorFinal implements Processador {


public Object processarRequisicao() {
return objeto;
}
}
public interface Processador {
public Object processarRequisicao();
}

84
Estratgias de Chain Of Responsibility

Pode-se implementar um padro de vrias


formas diferentes. Cada forma chamada de
estratgia (ou idiom*)
Chain of Responsibility pode ser implementada
com estratgias que permitem maior ou menor
acoplamento entre os participantes
Usando um mediador: s o mediador sabe quem o
prximo participante da cadeia
Usando delegao: cada participante conhece o seu
sucessor
* No so sinnimos: diferem no detalhamento e dependncia de linguagem 85
Questes

Cite exemplos de correntes de


responsabilidade em
Aplicaes
API Java

86
10
Flyweight
"Usar compartilhamento para suportar grandes quantidades
de objetos refinados eficientemente." [GoF]

87
Problema
Pool de objetos
imutveis
compartilhados

88
Estrutura
if(flyweightPool.containsKey(id)) {
return (Flyweight)flyweightMap.get(id);
} else {

de Flyweight
Flyweight fly = new FlyweightConcreto( genKey() );
flyweightPool.put(fly.getKey(), fly);
return fly;
}

FlyweightFactory interface
flyweightPool Flyweight
operacao(estadoMutavel)
getFlyweight(id)

FlyweightConcreto FlyweightConcretoNaoCompartilhado

estadoImutavel estadoMutavel
operacao(estadoMutavel) operacao(estadoMutavel)

Cliente

89
Prs e Contras
Flyweight uma soluo para construo de
aplicaes usando objetos imutveis
Ideal para objetos que oferecem servios (guardados em
caches e em pools)
Ideal para objetos que podem ser usados para construir
outros objetos
Problemas
Possvel impacto na performance (se houver muitas
representaes diferentes, elas no podem ser alteradas, e
preciso criar muitos objetos)

90
Questes

Cite exemplos de Flyweight em Java


Aplicaes
API Java
Seria uma boa idia ter principalmente
objetos imutveis em uma aplicao
Quais as vantagens?
Quais as desvantagens? Cenrios?
Solues?

91
Resumo: Quando usar?
Singleton
Quando apenas uma instncia for permitida
Observer
Quando houver necessidade de notificao automtica
Mediator
Para controlar a interao entre dois objetos independentes
Proxy
Quando for preciso um intermedirio para o objeto real
Chain of Responsibility
Quando uma requisio puder ou precisar ser tratada por
um ou mais entre vrios objetos
Flyweight
Quando for necessrio reutilizar objetos visando
performance (cuidado com o efeito oposto!)
92
Questes

Qual a diferena entre


Observer e Mediator
Flyweight e Composite
Singleton e Faade
Mediator e Proxy
Chain of Responsibility e Adapter

93
Alm dos construtores
Construtores em Java definem maneiras padro de
construir objetos. Sobrecarga permite ampla flexibilidade
Alguns problemas em depender de construtores
Cliente pode no ter todos os dados necessrios para
instanciar um objeto
Cliente fica acoplado a uma implementao concreta (precisa
saber a classe concreta para usar new com o construtor)
Cliente de herana pode criar construtor que chama mtodos
que dependem de valores ainda no inicializados (vide
processo de construo)
Objeto complexo pode necessitar da criao de objetos
menores previamente, com certo controle difcil de
implementar com construtores
No h como limitar o nmero de instncias criadas
94
Alm dos construtores

Padres que oferecem alternativas construo de


objetos
Builder: obtm informao necessria em passos antes de
requisitar a construo de um objeto
Factory Method: adia a deciso sobre qual classe concreta
instanciar
Abstract Factory: constuir uma famlia de objetos que
compartilham um "tema" em comum
Prototype: especificar a criao de um objeto a partir de
um exemplo fornecido
Memento: reconstruir um objeto a partir de uma verso
que contm apenas seu estado interno
95
11
Builder

"Separar a construo de um objeto complexo de sua


representao para que o mesmo processo de construo
possa criar representaes diferentes." [GoF]

96
Cliente
Cliente precisa de uma casa. Passa as
informaes necessrias para seu diretor Problema
Diretor Utilizando as informaes passadas pelo cliente, ordena a criao da
casa pelo construtor usando uma interface uniforme

Construtor O construtor habilitado para construir qualquer objeto complexo


passoUm()
(poderia, por exemplo, construir um prdio em vez de uma casa,
passoDois()
obterProduto() caso o cliente tivesse indicado esse desejo)

ConstrutorDeCasas ConstrutorDePredios

O Diretor selecionou um construtor de casas e chamou os


passos necessrios da construo
Quando o produto estiver pronto, o cliente pode buscar seu
produto diretamente do construtor.
obterProduto()
Cliente

97
Exemplo
Diretor 1..* Construtor
construir() construirParteUm()
construirParteDois()

while(objetos.hasNext()) {
Construtor c = (Construtor) objetos.next();
c.construirParteUm();
...
c.construirParteDois();
} ConstrutorDeCasas
-resultadoFinal
Cliente construirParteUm()
construirParteDois()
getCasa():Casa

ConstrutorDePredios
-resultadoFinal
construirParteUm()
construirParteDois()
getPredio():Predio

98
builders Exemplo: GoF
TextConverter
RTFReader builder convChar(char)
parseRTF() convFontChange(Font)
convParagraph()

TeXConverter TextWidgetConverter
convChar(char) convChar(char)
convFontChange(Font) convFontChange(Font)
convParagraph() convParagraph()
getTeXText() getTextWidget()

create
while (token = (Glyph)tokens.hasNext()){
switch token.type { create
CHAR: TeXText TextWidget
builder.convChar(token.Char)
FONT:
builder.convFontChange(token.Font)
PARA:
builder.convParagraph()
Client
}
}
99
Seqncia de Builder
cliente

create
:ConstrutorConcreto
create
:Diretor

construir()

construirParteUm()

construirParteDois()

construirParteTres()

getResultados()

100
Quando usar?
Builder permite que uma classe se preocupe com
apenas uma parte da construo de um objeto. til
em algoritmos de construo complexos
Use-o quando o algoritmo para criar um objeto complexo
precisar ser independente das partes que compem o
objeto e da forma como o objeto construdo
Builder tambm suporta substituio dos
construtores, permitindo que a mesma interface seja
usada para construir representaes diferentes dos
mesmos dados
Use quando o processo de construo precisar suportar
representaes diferentes do objeto que est sendo
construdo
101
Questes

Cite implementaes de Builder na API Java!

102
12
Factory Method

"Definir uma interface para criar um objeto mas deixar que


subclasses decidam que classe instanciar. Factory Method
permite que uma classe delegue a responsabilidade de
instanciamento s subclasses." [GoF]

103
O acesso a um objeto concreto ser Problema
atravs da interface conhecida ShapeFactory

atravs de sua superclasse, mas


Polygon
cliente tambm no quer (ou no draw()
pode) saber qual implementao
concreta est usando Rectangle
Shape draw()
Client draw()

Circle
draw()

Shape shape = new Rectangle();


Shape shape = ShapeFactory.getShape("rect"); return new Rectangle()
shape.draw(); neste contexto

public static Shape getShape(String type) {


ShapeFactory factory = (ShapeFactory)typeMap.get(type);
return factory.getShape(); // non-static Factory Method
}
104
Como implementar?
possvel criar um objeto sem ter
conhecimento algum de sua classe concreta?
Esse conhecimento deve estar em alguma parte
do sistema, mas no precisa estar no cliente
FactoryMethod define uma interface comum para
criar objetos
O objeto especfico determinado nas diferentes
implementaes dessa interface
O cliente do FactoryMethod precisa saber sobre
implementaes concretas do objeto criador do
produto desejado
105
Estrutura de Criador

Factory Method
getProduto():Produto
operacao()

produto = Produto produto = getProduto();


new ProdutoConcretoA()
return produto;

CriadorConcretoA CriadorConcretoB

produto:ProdutoConcrA produto:ProdutoConcrB
Produto getProduto():Produto getProduto():Produto
metodo()

produto =
ProdutoConcretoA new ProdutoConcretoB()
metodo() return produto;

ProdutoConcretoB
metodo()
106
Estrutura de ShapeFactory
Factory Method getShape():Shape

shape = return getShape();


new Circle()
return shape;

CircleFactory RectangleFactory

shape:Circle shape:Rectangle
Shape getShape():Shape getShape():Shape
draw()

shape =
Circle new Rectangle()
draw() return shape;

Rectangle
draw()
107
13
Abstract Factory

"Prover uma interface para criar famlias de objetos


relacionados ou dependentes sem especificar suas classes
concretas." [GoF]

108
Problema
Criar uma famlia de objetos relacionados sem
conhecer suas classes concretas

Cliente

109
Estrutura de Abstract Factory
abstrao

FabricaAbstrata interface interface


ProdutoUm ProdutoDois
criarProdutoUm():ProdutoUm
operacaoUm() operacaoDois()
criarProdutoDois():ProdutoDois

implA

ProdutoConcretoUm
return new operacaoUm()
implA.ProdutoConcretoUm(); FabricaConcretaA
ProdutoConcretoDois
criarProdutoUm()
operacaoDois()
criarProdutoDois()

implB

ProdutoConcretoUm
operacaoUm()
FabricaConcretaB
ProdutoConcretoDois
criarProdutoUm()
return new operacaoDois()
criarProdutoDois()
implB.ProdutoConcretoDois();
110
Questes

Cite exemplos de Abstract Factory no J2SDK


Qual a diferena entre Factory Method e
Abstract Factory?

111
14
Prototype

"Especificar os tipos de objetos a serem criados usando uma


instncia como prottipo e criar novos objetos ao copiar
este prottipo." [GoF]

112
Problema
Criar um objeto novo, mas aproveitar o estado previamente
existente em outro objeto

new setYYY()
addXXX()

clone()

113
Estrutura de Prototype

Cliente Prottipo
operacao() clonar()

Prottipo p1 = new PrototipoConcreto();


p1.mudaEstado(estado);
p2 = p1.clonar();

ProttipoConcretoUm ProttipoConcretoUm
clonar() clonar()

retorna cpia de si prprio retorna cpia de si prprio

114
Resumo

O padro Prototype permite que um cliente


crie novos objetos ao copiar objetos existentes
Uma vantagem de criar objetos deste modo
poder aproveitar o estado existente de um
objeto
Questo
Voc conhece alguma implementao de
Prototype na API Java?

115
15
Memento

"Sem violar o encapsulamento, capturar e externalizar o


estado interno de um objeto para que o objeto possa ter
esse estado restaurado posteriormente." [GoF]

116
Problema

preciso guardar informaes sobre um objeto


suficientes para desfazer uma operao, mas essas
informaes no devem ser pblicas
Editor Grfico Editor Grfico Editor Grfico

Antes Ao Undo!
No funcionou!
Preciso de mais
informao!
117
Soluo: Memento

Um memento um pequeno repositrio para guardar


estado dos objetos
Pode-se usar outro objeto, um string, um arquivo
Memento guarda um snapshot no estado interno de
outro objeto - a Fonte
Um mecanismo de Undo ir requisitar um memento da
fonte quando ele necessitar verificar o estado desse objeto
A fonte reinicializa o memento com informaes que
caracterizam seu estado atual
S a fonte tem permisso para recuperar informes do
memento (o memento "opaco" aos outros objetos)
118
Quando usar?

Use Memento quando


Um snapshot do (parte do) estado de um objeto
precisa ser armazenada para que ele possa ser
restaurado ao seu estado original posteriormente
Uma interface direta para se obter esse estado
iria expor detalhes de implementao e quebrar o
encapsulamento do objeto

119
Estrutura de Memento
Nunca opera sobre ou examina o
contedo de um memento

Cria um memento contendo


snapshot de seu estado atual e usa o Zelador
Memento para restaurar seu estado
interno
pacote

Fonte Memento
estado -estado
criarMemento() ~getEstado()
setMemento(Memento m) ~setEstado()

estado = m.getEStado() return new Memento(estado)

Package-private (friendly)
S a Fonte tem acesso!

120
Seqncia

:Zelador :Fonte

criarMemento() create
m:Memento

setEstado()

setMemento(m)

getEstado()

121
Exemplo genrico Memento em Java
package memento;

public class Fonte {


private Memento memento; Implementar Memento
em Java pode ser
private Object estado;
public Memento criarMemento() {

}
return new Memento(); realizado simplesmente
public void setMemento(Memento m) { aplicando o
}
memento = m;
encapsulamento de
} pacotes
Pacotes pequenos
package memento;
contendo apenas as classes
public class Memento { que precisam compartilhar
private Object estado; estado
Memento() { }
void setEstado(Object estado) {
this.estado = estado;
}
Object getEstado() {
return estado;
}
}
122
Resumo: Quando usar?
Builder
Para construir objetos complexos em vrias etapas e/ou que
possuem representaes diferentes
Factory Method
Para isolar a classe concreta do produto criado da interface
usada pelo cliente
Abstract Factory
Para criar famlias inteiras de objetos que tm algo em
comum sem especificar suas interfaces.
Prototype
Para criar objetos usando outro como base
Memento
Para armazenar o estado de um objeto sem quebrar o
encapsulamento. O uso tpico deste padro na
implementao de operaes de Undo.
123
Introduo: operaes
Definies essenciais
Operao: especificao de um servio que pode ser
requisitado por uma instncia de uma classe. Exemplo:
operao toString() implementada em todas as classes.
Mtodo: implementao de uma operao. Um mtodo
tem uma assinatura. Exemplo: cada classe implementa
toString() diferentemente
Assinatura: descreve uma operao com um nome,
parmetros e tipo de retorno. Exemplo: public String
toString()
Algoritmo: uma seqncia de instrues que aceita
entradas e produz sada. Pode ser um mtodo, parte de
um mtodo ou pode consistir de vrios mtodos.
124
Alm das operaes comuns
Vrios padres lidam com diferentes formas de
implementar operaes e algoritmos
Template Method: implementa um algoritmo em um mtodo
adiando a definio de alguns passos do algoritmo para que
subclasses possam defini-los
State: distribui uma operao para que cada classe represente
um estado diferente; encapsula um estado
Strategy: encapsula um algoritmo fazendo com que as
implementaes sejam intercambiveis
Command: encapsula uma instruo em um objeto
Interpreter: distribui uma operao de tal forma que cada
implementao se aplique a um tipo de composio diferente
125
16
Template Method

"Definir o esqueleto de um algoritmo dentro de uma


operao, deixando alguns passos a serem preenchidos
pelas subclasses. Template Method permite que suas
subclasses redefinam certos passos de um algoritmo sem
mudar sua estrutura." [GoF]
126
Classe Problema
Algoritmos resultantes
void concreto() {
Algoritmo
Classe x =
um() new ClasseConcretaUm()
x.concreto()
trs()

dois()
}

abstract void um();


Mtodos
abstract int dois(); abstratos
abstract Object tres();

Classe x =
new ClasseConcretaDois()
x.concreto()

ClasseConcretaUm ClasseConcretaDois
um() um()

trs() trs()

dois() dois()
127
Soluo: Template Method

O que um Template Method


Um Template Method define um algoritmo em
termos de operaes abstratas que subclasses
sobrepem para oferecer comportamento concreto
Quando usar?
Quando a estrutura fixa de um algoritmo puder ser
definida pela superclasse deixando certas partes
para serem preenchidos por implementaes que
podem variar

128
Template Method em Java
public abstract class Template {
protected abstract String link(String texto, String url);
protected String transform(String texto) { return texto; }
public final String templateMethod() {
String msg = "Endereo: " + link("Empresa", "http://www.empresa.com");
return transform(msg);
}

public class XMLData extends Template {


protected String link(String texto, String url) {
return "<endereco xlink:href='"+url+"'>"+texto+"</endereco>";
}
}

public class HTMLData extends Template {


protected String link(String texto, String url) {
return "<a href='"+url+"'>"+texto+"</a>";
}
protected String transform(String texto) {
return texto.toLowerCase();
}
}

129
Exemplo no J2SDK
O mtodo Arrays.sort (java.util) um bom exemplo de
Template Method. Ele recebe como parmetro um objeto do
tipo Comparator que implementa um mtodo compare(a, b) e
utiliza-o para definir as regras de ordenao
public class MedeCoisas implements Comparator<Coisa> {
public int compare(Coisa c1, Coisa c2) {
if (c1.getID() > c2.getID()) return 1; Coisa
if (c1.getID() < c2.getID()) return -1; id: int
if (c1.getID() == c2.getID()) return 0;
}
}

...
Coisa coisas[] = new Coisa[10]; Mtodo retorna 1, 0 ou -1
coisas[0] = new Coisa("A"); para ordenar Coisas pelo ID
coisas[1] = new Coisa("B");
...
Arrays.sort(coisas, new MedeCoisas());
...
130
Questes

Cite outros exemplos de Template Method


Em Java
Em frameworks
Que outras aplicaes poderiam ser
implementadas com Template Method?

131
17
State

"Permitir a um objeto alterar o seu comportamento quanto


o seu estado interno mudar. O objeto ir aparentar mudar
de classe." [GoF]

132
Problema

Desconectado :Objeto

operao
if (estado == desconectado) {
faaIsto();
} else if (estado == conectado) {
Conectado faaAquilo();
} else {
faa();
}

Transmitindo operao
estado.faa()

Objetivo: usar objetos para representar estados e


polimorfismo para tornar a execuo de tarefas
dependentes de estado transparentes
133
Exemplo [GoF]

TCPConnection TCPState
open() state open()
close() close()
acknowldge() acknowldge()

state.open()

TCPEstablished TCPListen TCPClosed


open() open() open()
close() close() close()
acknowldge() acknowldge() acknowldge()

Sempre que a aplicao mudar de estado, o objeto


TCPConnection muda o objeto TCPState que est usando

134
Estrutura de State
Contexto interface
Estado
estado:Estado
requisicao() processar()

estado.processar()

EstadoConcretoUm EstadoConcretoDois
...
processar() processar()

Contexto:
define a interface de interesse aos clientes
mantm uma instncia de um EstadoConcreto que define o estado atual
Estado
define uma interface para encapsular o comportamento associado com um
estado particular do contexto
EstadoConcreto
Implementa um comportamento associado ao estado do contexto
135
State em Java
public class GatoQuantico {
public final Estado VIVO = new EstadoVivo();
public final Estado MORTO = new EstadoMorto();
public final Estado QUANTICO = new EstadoQuantico();

private Estado estado;

public void setEstado(Estado estado) {


this.estado = estado;
} public class EstadoVivo {
public void miar() {
public void miar() { System.out.println("Meaaaooww!!");
estado.miar(); }
} }
}

public interface Estado {


void miar();
}

public class EstadoMorto { public class EstadoQuantico {


public void miar() { public void miar() {
System.out.println("Buu!"); System.out.println("Hello Arnold!");
} }
} }
136
18
Strategy

"Definir uma famlia de algoritmos, encapsular cada um, e


faz-los intercambiveis. Strategy permite que algoritmos
mudem independentemente entre clientes que os utilizam."
[GoF]

137
Problema
Vrias estratgias, escolhidas de
acordo com opes ou condies
if (guerra && inflao > META) {
if (guerra && inflao > META) { plano = new Estrategia_C();
doPlanoB(); } else if (guerra && recesso) {
else if (guerra && recesso) { plano = new Estrategia_B();
doPlanoC(); } else {
} else { plano = new Estrategia_A();
doPlanejado(); }
}
plano.executar();

Idntico a state na
implementao. Estratgia
executar();
Diferente na inteno!

Estratgia_A Estratgia_B Estratgia_C


executar(); executar(); executar();
138
Estrutura de Strategy
Contexto interface
Estrategia
strat:Estrategia
requisicao() executarAlgoritmo()

strat.executarAlgoritmo()

...

EstrategiaConcretaUm EstrategiaConcretaDois
...
executarAlgoritmo() executarAlgoritmo()

Um contexto repassa requisies de seus clientes para sua estratgia.


Clientes geralmente criam e passam uma EstategiaConcreta para o
contexto. Depois, clientes interagem apenas com o contexto
Estrategia e Contexto interagem para implementar o algoritmo escolhido.
Um contexto pode passar todos os dados necessrios ou uma cpia de si
prprio
139
Quando usar?

Quando classes relacionadas forem diferentes apenas


no seu comportamento
Strategy oferece um meio para configurar a classe com um
entre vrios comportamentos
Quando voc precisar de diferentes variaes de um
mesmo algoritmo
Quando um algoritmo usa dados que o cliente no
deve conhecer
Quando uma classe define muitos comportamentos,
e estes aparecem como mltiplas declaraes
condicionais em suas operaes

140
public class Guerra {
Estrategia acao; Strategy em Java
public void definirEstrategia() {
if (inimigo.exercito() > 10000) { public interface Estrategia {
acao = new AliancaVizinho(); public void atacar();
} else if (inimigo.isNuclear()) { public void concluir();
acao = new Diplomacia(); }
} else if (inimigo.hasNoChance()) {
acao = new AtacarSozinho(); public class AtacarSozinho
} implements Estrategia {
} public void atacar() {
plantarEvidenciasFalsas();
public void declararGuerra() { soltarBombas();
acao.atacar(); derrubarGoverno();
} }
public void encerrarGuerra() { public void concluir() {
acao.concluir(); estabelecerGovernoAmigo();
} }
} }

public class AliancaVizinho public class Diplomacia


implements Estrategia { implements Estrategia {
public void atacar() { public void atacar() {
vizinhoPeloNorte(); recuarTropas();
atacarPeloSul(); proporCooperacaoEconomica();
... ...
}
public void concluir() { }
dividirBeneficios(...); public void concluir() {
dividirReconstruo(...); desarmarInimigo();
} }
} } 141
Questes

Cite exemplos de Strategy


Qual a diferena entre Strategy e State?

142
19
Command

"Encapsular uma requisio como um objeto, permitindo


que clientes parametrizem diferentes requisies, filas ou
requisies de log, e suportar operaes reversveis." [GoF]

143
Problema
Command
execute(): Object

new NovoSocioCommand

edit EditarCommand

del RemoverCommand

get MostrarSocioCommand

all ListarTodosCommand
all
Cliente
Aplicao
Complexa Command c = getCommand("all");

service() {
...
Object result = c.execute();
...
}

144
Estrutura de Command
Executor Comando
cmd:Comando
executar()
servio()

cmd.executar()

...

ComandoConcretoUm ComandoConcretoDois
cria
Cliente estado estado ...
executar() executar()

receptor.ao()

Receptor
ao()

145
Command em Java
public interface Command { public interface NewCommand implements Command {
public Object execute(Object arg);
} public NewCommand(Database db) {
this.db = db;
}
public class Server {
private Database db = ...; public Object execute(Object arg) {
private HashMap cmds = new HashMap(); Data d = (Data)arg;
int id = d.getArg(0);
public Server() { String nome = d.getArg(1);
initCommands(); db.insert(new Member(id, nome));
} }
}
private void initCommands() {
cmds.put("new", new NewCommand(db));
cmds.put("del",
new DeleteCommand(db));
... public class DeleteCommand implements Command {
}
public DeleteCommand(Database db) {
public void service(String cmd, this.db = db;
Object data) { }
...
Command c = (Command)cmds.get(cmd); public Object execute(Object arg) {
... Data d = (Data)arg;
Object result = c.execute(data); int id = d.getArg(0);
... db.delete(id);
} }
} }

146
Questes

Cite exemplos de Command


Na API Java
Em frameworks
Qual a diferena entre
Strategy e Command?
State e Command?
State e Strategy?

147
State, Strategy e Command
Diferentes intenes, diagramas e
implementaes similares (ou idnticas)
Como distinguir?
State representa um estado (substantivo) e
geralmente est menos accessvel (a mudana de
estado pode ser desencadeada por outro estado)
Strategy representa um comportamento (verbo)
e escolhida dentro da aplicao (a ao pode ser
desencadeada por ao do cliente ou estado)
Command representa uma ao escolhida e
iniciada por um cliente externo (usurio)
148
20
Interpreter

"Dada uma linguagem, definir uma representao para sua


gramtica junto com um interpretador que usa a
representao para interpretar sentenas na linguagem."
[GoF]

149
Problema
Se comandos esto representados como objetos, eles
podero fazer parte de algoritmos maiores
Vrios padres repetitivos podem surgir nesses algoritmos
Operaes como iterao ou condicionais podem ser
frequentes: represent-las como objetos Command
Soluo em OO: elaborar uma gramtica para
calcular expresses compostas por objetos
Interpreter uma extenso do padro Command (ou um
tipo de Command; ou uma micro-arquitetura construda
com base em Commands) em que toda uma lgica de
cdigo pode ser implementada com objetos

150
Exemplo [GoF]

RegularExpression
interpret()

LiteralExpression expr1
SequenceExpression
literal expr2
interpret() interpret()

alternative1
RepetitionExpression AlternationExpression alternative2
interpret() interpret()

151
Questes

Qual a diferena entre Command e Interpreter?


Cite exemplos de implementaes na API Java e em
frameworks que voc conhece

152
Resumo: quando usar?
Template Method
Para compor um algoritmo feito por mtodos abstratos que
podem ser completados em subclasses
State
Para representar o estado de um objeto
Strategy
Para representar um algoritmo (comportamento)
Command
Para representar um comando (ao imperativa do cliente)
Interpreter
Para realizar composio com comandos e desenvolver uma
linguagem de programao usando objetos
153
Introduo: Extenso

Extenso a adio de uma classe, interface


ou mtodo a uma base de cdigo existente [2]
Formas de extenso
Herana (criao de novas classes)
Delegao (para herdar de duas classes, pode-se
estender uma classe e usar delegao para
"herdar" o comportamento da outra classe)
Desenvolvimento em Java sempre uma
forma de extenso
Extenso comea onde o reuso termina
154
Exemplo de extenso
por delegao ClasseConcretaUm
metodoUm()
ClasseConcretaDois
metodoDois() metodoCinco()

Efeito metodoTres() metodoQuatro()

Desejado
ClasseDerivada

ClasseConcretaUm interface
InterfaceDois
metodoUm()
metodoDois() metodoCinco() Efeito Possvel
metodoTres() metodoQuatro()
em Java

ClasseDerivada
ClasseConcretaDois
deleg:ClasseConcretaUm
deleg metodoCinco()
metodoQuatro() metodoQuatro()
metodoCinco() Classes existentes

deleg.metodoQuatro() Classes novas


155
Alm da extenso
Tanto herana como delegao exigem que se saiba, em
tempo de compilao, que comportamentos so
desejados. Os patterns permitem acrescentar
comportamentos em um objeto sem mudar sua classe
Principais classes
Command (captulo anterior)
Template Method (captulo anterior)
Decorator: adiciona responsabilidades a um objeto
dinamicamente.
Iterator: oferece uma maneira de acessar uma coleo de
instncias de uma classe carregada.
Visitor: permite a adio de novas operaes a uma classe
sem mudar a classe.
156
21
Decorator

"Anexar responsabilidades adicionais a um objeto


dinamicamente. Decorators oferecem uma alternativa
flexvel ao uso de herana para estender uma
funcionalidade." [GoF]

157
Requisio
Problema
Requisio

getResultado()

getResultado()
getX()
getResultado()
getY()
getZ()

getResultado()
getX()

158
Estrutura de Decorator
Componente
operao()

ComponenteConcreto Decorador
operao() operao() componente.operao();

super.operao();
comportamentoAdicional();

DecoradorConcretoUm DecoradorConcretoDois
estadoAdicional comportamentoAdicional()
operacao() operacao()

159
public abstract class DecoradorConcretoUm extends Decorador {
public DecoradorConcretoUm (Componente componente) { Decorator
}
super(componente);

public String getDadosComoString() {


em Java
return getDados().toString(); public abstract class DecoradorConcretoUm
} extends Decorador {
private Object transformar(Object o) { private Object estado;
... public DecoradorConcretoUm (Componente comp,
} Object estado) {
public Object getDados() { super(comp);
return transformar(getDados()); this.estado = estado;
} }
public void operacao(Object arg) { ...
// ... comportamento adicional public void operacao(Object arg) {
componente.operacao(arg); // ... comportamento adicional
} super.operacao(estado);
} // ...
}
}

public class ComponenteConcreto implements Componente {


private Object dados;
public Object getDados() { public abstract class Decorador implements Componente {
return dados; private Componente componente;
} public Decorador(Componente componente) {
public void operacao(Object arg) { this.componente = componente;
... }
} public Object getDados() {
} return componente.getDados();
}
public interface Componente { public void operacao(Object arg) {
Object getDados(); componente.operacao(arg);
void operacao(Object arg); }
} } 160
Exemplo: I/O Streams

Um componente
concreto

// objeto do tipo File


File tanque = new File("agua.txt");
// componente FileInputStream
// cano conectado no tanque
FileInputStream cano =
new FileInputStream(tanque);
// read() l um byte a partir do cano
byte octeto = cano.read();

161
Concatenao
de
I/O streams
Concatenao do
decorador
// partindo do cano (componente concreto)
FileInputStream cano = new FileInputStream(tanque);
// decorador chf conectado no componente
InputStreamReader chf = new InputStreamReader(cano);
// pode-se ler um char a partir de chf (mas isto impede que
// o char chegue ao fim da linha: h um vazamento no cano!)
char letra = chf.read();
Uso de mtodo com
comportamento alterado
// decorador br conectado no decorador chf
BufferedReader br = new BufferedReader (chf);
// l linha de texto a de br Comportamento
String linha = br.readLine(); adicional
162
Questes

Cite outros exemplos de Decorator no J2SDK


e em frameworks que voc conhece

163
22
Iterator

"Prover uma maneira de acessar os elementos de um objeto


agregado seqencialmente sem expor sua representao
interna." [GoF]

164
Problema
Tipo de
referncia Coleo arbitrria de objetos
genrico Iterator (array, hashmap, lista, conjunto,
pilha, tabela, ...)

Object o =
iterator.next()

iterator.hasNext() ?

produz
Iterator Coleo
tem

165
Para que serve?
Iterators servem para acessar o contedo de um agregado
sem expor sua representao interna
Oferece uma interface uniforme para atravessar diferentes
estruturas agregadas
Iterators so implementados nas colees do Java. obtido
atravs do mtodo iterator() de Collection, que devolve uma
instncia de java.util.Iterator.
Interface java.util.Iterator:
package java.util;
public interface Iterator<E> {
boolean hasNext();
Object next();
void remove();
}

iterator() um exemplo de Factory Method


166
Questes
Quantos iterators voc conhece nas APIs da
linguagem Java (alm de java.util.Iterator)?

167
23
Visitor

"Representar uma operao a ser realizada sobre os


elementos de uma estrutura de objetos. Visitor permite
definir uma nova operao sem mudar as classes dos
elementos nos quais opera." [GoF]

168
Problema
Operaes Cliente Operao para suporte
fixas a extenses

Interface

Operaes
novas
plugveis
169
Para que serve?

Visitor permite
Plugar nova funcionalidade em objetos sem
precisar mexer na estrutura de herana
Agrupar e manter operaes relacionadas em uma
classe e aplic-las, quando conveniente, a outras
classes (evitar espalhamento e fragmentao de
interesses)
Implementar um Iterator para objetos no
relacionados atravs de herana

170
Antes Node
typeCheck()
generateCode()
Visitor: exemplo GoF
Depois
VariableRefNode AssignmentNode
typeCheck() typeCheck() NodeVisitor
generateCode() generateCode() visit(AssignmentNode)
visit(VariableRefNode)

TypeChkVisitor CodeGenVisitor
visit(AssignmentNode) visit(AssignmentNode)
visit(VariableRefNode) visit(VariableRefNode)

Depois
Node v.visit(this)
accept(NodeVisitor)

AssignmentNode VariableRefNode
accept(NodeVisitor v) v.visit(this) accept(NodeVisitor v)
171
Estrutura de Visitor interface
Visitante
visitarA(ElementoConcretoA)
visitarB(ElementoConcretoB)
Cliente

VisitanteConcretoUm VisitanteConcretoDois
visitarA(ElementoConcretoA) visitarA(ElementoConcretoA)
visitarB(ElementoConcretoB) visitarB(ElementoConcretoB)

Elemento
EstruturaDeObjetos
aceitar(Visitante)

ElementoConcretoA ElementoConcretoB
operacaoA() operacaoB()
aceitar(Visitante v) aceitar(Visitante v)

v.visitarA(this) v.visitarB(this)

172
Diagrama de seqncia
:EstruturaDeObjetos :ElementoConcretoA :ElementoConcretoB :VisitanteConcreto

aceitar(:Visitante)
visitarA(:ElementoConcretoA)

operacaoA()

aceitar(:Visitante)
visitarB(:ElementoConcretoB)

operacaoB()

173
Refatoramento para Visitor em Java: Antes
public interface Documento_1 { public class Texto_1
public void gerarTexto(); implements Documento_1 {
public void gerarHTML(); public void gerarTexto() {...}
public boolean validar(); public void gerarHTML() {...}
} public boolean validar() {...}
...
}
talvez o mais complexo dos
padres GoF public class Planilha_1
implements Documento_1 {
public void gerarTexto() {...}
public class Cliente { public void gerarHTML() {...}
public static void main(String[] args) { public boolean validar() {...}
Documento_1 doc = new Texto_1(); ...
Documento_1 doc2 = new Grafico_1(); }
Documento_1 doc3 = new Planilha_1();
doc.gerarTexto(); public class Grafico_1
doc.gerarHTML(); implements Documento_1 {
if (doc.validar()) public void gerarTexto() {
System.out.println(doc + " valido!"); System.out.println("Nao impl.");
doc2.gerarTexto(); }
doc2.gerarHTML(); public void gerarHTML() {
if (doc2.validar()) System.out.println("HTML gerado");
System.out.println(doc2 + " valido!"); }
doc3.gerarTexto(); public boolean validar() {
doc3.gerarHTML(); return true;
if (doc3.validar()) }
System.out.println(doc3 + " valido!"); public String toString() {
return "Grafico";
} }
} } 174
Visitor em Java (Depois)
public interface Visitante {
public Object visitar(Planilha p);
public Object visitar(Texto t);
public Object visitar(Grafico g);
}

public class GerarHTML implements Visitante {


public Object visitar(Planilha p) { public interface Documento {
p.gerarHTML(); return null; } public Object aceitar(Visitante v);
public Object visitar(Texto t) { }
t.gerarHTML(); return null; }
public Object visitar(Grafico g) { public class Planilha implements Documento {
g.gerarPNG(); } public Object aceitar(Visitante v) {
} return v.visitar(this);
}
public class Validar implements Visitante { public void gerarHTML() {...}
public Object visitar(Planilha p) { public void gerarTexto() {...}
return new Boolean(true); } public String toString() {...}
public Object visitar(Texto t) { }
return new Boolean(true); }
public class Texto implements Documento {
public Object visitar(Grafico g) {
public Object aceitar(Visitante v) {
return new Boolean(true); }
return v.visitar(this);
}
}
public void gerarHTML() {...}
public class Cliente { public void gerarTexto() {...}
public static void main(String[] args) { public String toString() {...}
Documento doc = new Texto(); }
doc.aceitar(new GerarTexto());
doc.aceitar(new GerarHTML()); public class Grafico implements Documento {
if (((Boolean)doc.aceitar( public Object aceitar(Visitante v) {
new Validar())).booleanValue()) { return v.visitar(this);
System.out.println(doc + " valido!"); }
} public void gerarPNG() {...}
} public String toString() {...}
} } 175
Prs e contras
Vantagens
Facilita a adio de novas operaes
Agrupa operaes relacionadas e separa operaes no
relacionadas: reduz espalhamento de funcionalidades e
embaralhamento
Desvantagens
D trabalho adicionar novos elementos na hierarquia:
requer alteraes em todos os Visitors. Se a estrutura
muda com frequncia, no use!
Quebra de encapsulamento: mtodos e dados usados pelo
visitor tm de estar acessveis
Alternativas ao uso de visitor
Aspectos (www.aopalliance.org e www.aspectj.org)
Hyperslices (www.research.ibm.com/hyperspace/ )
176
Resumo: quando usar?
Decorator
Para acrescentar recursos e comportamento a um
objeto existente, receber sua entrada e poder
manipular sua sada.
Iterator
Para navegar em uma coleo elemento por
elemento
Visitor
Para estender uma aplicao com novas
operaes sem que seja necessrio mexer na
interface existente.
177
Voc sabe distinguir os padres GoF

Faa alguns testes!

178
Padres GRASP
Padres bsicos Padres GRASP refletem
Information Expert prticas mais pontuais da
Creator aplicao de tcnicas OO
High Cohesion
Low Coupling
Padres GoF exploram
Controller solues mais especficas
Padres avanados
Polymorphism
Pure Fabrication Padres GRASP ocorrem
Indirection na implementao de
vrios padres GoF
Protected Variations

179
Expert (especialista de informao)

Problema
Precisa-se de um princpio geral para atribuir
responsabilidades a objetos
Durante o design, quando so definidas interaes entre
objetos, fazemos escolhas sobre a atribuio de
responsabilidades a classes
Soluo
Atribuir uma responsabilidade ao especialista de informao:
classe que possui a informao necessria para cumpri-la
Comece a atribuio de responsabilidades ao declarar
claramente a responsabilidade

180
Expert
No sistema abaixo, uma classe precisa saber o total
geral de uma venda (Sale). Que classe deve ser a
responsvel?

Sale possui informaes sobre


SalesLineItems (knowing)

Fonte: [4] 181


Expert (2)
A nova responsabilidade conduzida por uma
operao no driagrama de interao
Um novo mtodo criado

Fonte: [4] 182


Expert(3)
Mas como a classe Sale vai calcular o valor total?
Somando os subtotais. Mas quem faz isto?
A responsabilidade para cada subtotal atribuda ao
objeto SalesLineItem (item de linha do pedido)

183
Expert (4)

O subtotal depende do preo. O objeto


ProductSpecification o especialista que conhece o
preo, portanto a responsabilidade dele.

184
Creator

Problema: Que classe deve ser responsvel pela


criao de uma nova instncia de uma classe?
Soluo: Atribua a B a responsabilidade de criar
A se:
B agrega A objetos
B contm A objetos
B guarda instncias de A objetos
B faz uso de A objetos
B possui dados para inicializao que ser passado
para A quando ele for criado.
185
Creator

Que classe deve ser responsvel por criar uma


instncia do objeto SalesLineItem abaixo?

Sale agrega muitos


SalesLineItems

186
Creator
A nova responsabilidade conduzida por uma
operao em um diagrama de interaes
Um novo mtodo criado na classe de design para expressar
isto.

Este mtodo precisa


ser definido em Sale

Fonte: [4] 187


High Cohesion

Problema
Como manter a complexidade sob controle?
Classes que fazem muitas tarefas no relacionadas
so mais difceis de entender, de manter e de
reusar, alm de serem mais vulnerveis mudana.
Soluo
Atribuir uma responsabilidade para que a coeso se
mantenha alta.

Voc sabe o que coeso?

188
Coeso

Coeso [Funcional]
Uma medida de quo relacionadas ou focadas
esto as responsabilidades de um elemento.
Exemplo
Uma classe Co coesa se tem operaes
relacionadas ao Co (morder, correr, comer, latir)
e apenas ao Co (no ter por exemplo, validar,
imprimirCao, listarCaes)
Alta coeso promove design modular

189
High Cohesion
Que classe responsvel por criar um pagamento (Payment) e
associ-lo a uma venda (Sale)?

Register assumiu responsabilidade por uma coisa que parte de


Sale (fazer um pagamento no responsabilidade de registrar)
190
High Cohesion

Nesta soluo, Register delega a responsabilidade a


Sale, diminuindo aumentando a coeso de Register
A criao do processo de pagamento agora
responsabilidade da venda e no do registro. Faz mais
sentido pois o pagamento parte de Sale.

191
Low Coupling (baixo acoplamento)
Problema
Como suportar baixa dependncia, baixo impacto devido a
mudanas e reuso constante?
Soluo
Atribuir uma responsabilidade para que o acoplamento
mantenha-se fraco.
Acoplamento
uma medida de quanto um elemento est conectado a, ou
depende de outros elementos
Uma classe com acoplamento forte depende de muitas
outras classes: tais classes podem ser indesejveis
O acoplamento est associado coeso: maior coeso,
menor acoplamento e vice-versa.
192
Low Coupling

Como devemos atribuir uma responsabilidade


para criar Payment e associ-lo com Sale?

Payment

Register

Sale

193
Low Coupling
Qual das opes abaixo suporta o menor
acoplamento?

Opo 1

Opo 2

194
Controller

Problema
Quem deve ser o responsvel por lidar com um evento de
uma interface de entrada?
Soluo
Atribuir responsabilidades para receber ou lidar com um
evento do sistema para uma classe que representa todo o
sistema (controlador de fachada front controller), um
subsistema e um cenrio de caso de uso (controlador de
caso de uso ou de sesso).
Este padro semelhante (ou equivalente) a um
padro GoF. Qual?

195
Controller

Um sistema contendo operaes de sistema


associados com eventos do sistema.

196
Controller: problema

197
Controller: soluo

A primeira soluo representa o sistema inteiro


A segunda soluo representa o destinatrio ou
handler de todos os eventos de um caso de uso

O diagrama acima no mostra o Controller, mas a transparncia da


comunicao (chamada do cliente, objeto que recebe a mensagem)
198
Outros padres

Padres GRASP avanados


Domine primeiro os cinco bsicos antes de explorar
estes quatro:
Polymorphism
Indirection
Pure Fabrication
Protected Variations
Outros padres
Dependency Injection (aplicao de Indirection)
Aspectos

199
GRASP: Polymorphism
Problema:
Como lidar com alternativas baseadas no tipo? Como criar
componentes de software plugveis?
Deseja-se evitar variao condicional (if-then-else): pouco
extensvel.
Deseja-se substituir um componente por outro sem afetar o
cliente.
Soluo
No use lgica condicional para realizar alternativas
diferentes baseadas em tipo. Atribua responsabilidades ao
comportamento usando operaes polimrficas
Refatore!

200
GRASP: Pure Fabrication

Problema
Que objeto deve ter a responsabilidade, quando voc no
quer violar High Cohesion e Low Coupling, mas as solues
oferecidas por Expert no so adequadas?
Atribuir responsabilidades apenas para classes do domnio
conceitual pode levar a situaes de maior acoplamento e
menos coeso.
Soluo
Atribuir um conjunto altamente coesivo de responsabilidades
a uma classe artificial que no representa um conceito do
domnio do problema.

201
GRASP: Protected Variations
Problema
Como projetar objetos, subsistema e sistemas para que as
variaes ou instabilidades nesses elementos no tenha um
impacto indesejvel nos outros elementos?
Soluo
Identificar pontos de variao ou instabilidade potenciais.
Atribuir responsabilidades para criar uma interface estvel
em volta desses pontos.
Encapsulamento, interfaces, polimorfismo, indireo e
padres; mquinas virtuais e brokers so motivados por este
princpio
Evite enviar mensagens a objetos muito distantes.

202
GRASP: Indirection
Problema
Onde atribuir uma responsabilidade para evitar
acoplamento direto entre duas ou mais coisas? Como
desacoplar objetos para que seja possvel suportar baixo
acoplamento e manter elevado o potencial de reuso?
Soluo
Atribua a responsabilidade a um objeto intermedirio para
mediar as mensagens entre outros componentes ou servios
para que no sejam diretamente acoplados.
O objeto intermedirio cria uma camada de indireo entre
os dois componentes que no mais dependem um do outro:
agora ambos dependem da indireo.
Veja uma aplicao em: Dependency Injection

203
Injeo de dependncias
(inverso de controle)

Um dos benefcios de usar interfaces


Em vez de A depende de B
A precisa achar ou criar B
A B
class A {
B b = new B();
}
Use
inteface
A InterB B class A {
InterB b;
A(InterB b) {
A depende de uma interface IB this.b = b;
B depende de uma interface IB }
A recebe implementao de B quando criado }
204
Injeo de dependncias (2)
Se A depende de InterB, fica fcil testar ou medir A usando uma
implementao/simulao de B para testes
inteface
ATest A InterB
SimulatedB

inteface
ATest A InterB

Interfaces devem ser pequenas


Um objeto pode implementar vrias interfaces
Facilita evoluo (interfaces grandes publicam um contrato grande que no
pode ser revogado)
Planeje interfaces em todos os objetos
Principalmente objetos que oferecem servios, singletons, etc.

205
Dependency Injection

Problema
Controle convencional: o prprio objeto cria ou
localiza suas dependncias: acoplamento!
ProgramadorJava
nome: String
certificacao:CertificacaoProgramadorJava
inscrever(): Certificado

JNDI
lookup(certificacaoSCEA)
new
CertificacaoProgramadorJava()

CertificacaoProgramadorJava CertificacaoArquitetoJ2EE
206
Exemplo: controle convencional

Linha 9: dependncia fortemente acoplada


Difcil de testar objeto sem testar dependncia
1:package faculdade;
2:
3:public class ProgramadorJava {
4: private String nome;
5: private CertificacaoProgramadorJava certificacao;
6:
7: public ProgramadorJava(String nome) {
8: this.nome = nome;
9: certificacao = new CertificacaoProgramadorJava();
10: }
11:
12: public Certificado inscrever() throws NaoAprovadoException {
13: return certificacao.iniciarTeste();
14: }
15:}

207
A dependncia

1:package faculdade;
2:
3:public class CertificacaoProgramadorJava {
4: public CertificacaoProgramadorJava() {}
5: public Certificado iniciarTeste()
throws NaoAprovadoException {
6: Certificado certificado = null;
7: // Realizar questoes
8:
9: return certificado;
10: }
11:}

208
Diminuindo o acoplamento

Melhor forma de eliminar acoplamento usar interfaces


Implementao dependente da interface
Cliente depende da interface, e no mais da implementao
3:public interface Certificacao {
4: public Object iniciarTeste() throws CertificacaoException;
5:}

3:public class CertificacaoProgramadorJava implements Certificacao {


4: public CertificacaoProgramadorJava() {}
5: public Object iniciarTeste() throws NaoAprovadoException {
6: Certificado certificado = new Certificado();
7: // Realizar questoes
8: certificado.setNota(90);
9:
10: return certificado;
11: }
12:}

209
Soluo

Em vez do programador buscar ou criar sua prpria certificao,


ela atribuda a ele
Para isto, deve haver mtodo para criar a associao

ProgramadorJava
Certificacao
nome: String
certificacao:CertificacaoProgramadorJava
inscrever(): Certificado
setCertificacao(Certificacao);

programador.setCertificacao(this)
CertificacaoArquitetoJ2EE

programador.setCertificacao(certJ2EE)
CertificacaoProgramadorJava

210
Inverso de controle
public interface Programador {
public Object inscrever() throws NaoAprovadoException;
}

3:public class ProgramadorJava implements Programador {


4: private String nome;
5: private CertificacaoProgramadorJava certificacao;
6:
7: public ProgramadorJava(String nome) {
8: this.nome = nome;
9: }
10:
11: public Object inscrever() throws NaoAprovadoException {
12: return certificacao.iniciarTeste();
13: }
14:
15: public void setCertificacao(Certificacao certificacao) {
16: this.certificacao = certificacao;
17: }
18:}
211
Aspectos: Separao de interesses

A separao de interesses objetivo essencial do processo de


decomposio da soluo de um problema
Decomposio deve continuar at que cada unidade da soluo possa ser
compreendida e construda
Cada unidade deve lidar com apenas um interesse
Separao de interesses eficiente promove cdigo de melhor
qualidade
Maior modularidade
Facilita atribuio de responsabilidades entre mdulos
Promove o reuso
Facilita a evoluo do software
Viabiliza anlise do problema dentro de domnios especficos

212
Tipos de interesse

Usando uma linguagem orientada a objetos, pode-se representar


de forma eficiente e modular as classes e procedimentos
Outros interesses so implementados como partes de classes e
partes ou composio de procedimentos

Aspectos genricos
Caractersticas mover() e Figura
Poderiam ser usados em
desenhar() poderiam ser mover()
desenhar() outras aplicaes
reutilizadas em outros
objetos
mover()
validarCoords()
Retngulo Crculo Tringulo // cdigo p/ mover
logarAcao()
mover() mover() mover()
desenhar() desenhar() desenhar()
desenhar()
// cdigo p/ desenhar
logarAcao()
213
Problema: scattering e tangling
public class VeiculoPassageiro Scattering: acrescentar um
extends Veiculo { requerimento causa
public void abastecer() {
super.abastecer() + gasolina;
espalhamento do cdigo
Logger.log(nome() + em vrias classes
" abastecido com gasolina");
} ...
public class VeiculoCarga
}
extends Veiculo {
public void abastecer() {
super.abastecer() + diesel;
public class VeiculoAereo Logger.log(nome() +
extends Veiculo { " abastecido com diesel");
public void abastecer() { } ...
// cdigo }
Logger.log(nome() +
" abastecido com " + Tangling: cdigo para
x + " litros"); implementar o requerimento
// cdigo
} ... se mistura com lgica do
} cdigo existente 214
Incluso de nova funcionalidade

Tambm sujeita a scattering e tangling


Funcionalidade espalhada por vrias classes (funcionalidade
consiste de mtodos contidos em vrias classes)
Funcionalidade misturada com outros recursos (no
representado por uma entidade separada)

public class VeiculoPassageiro public class VeiculoCarga


extends Veiculo { extends Veiculo {
public void abastecer() {...} public void abastecer() {...}
public void carregar() {...} public Apolice segurar() {
public Apolice segurar() { Apolice a = new Apolice();
Apolice a = // preenche apolice p/
new Apolice(...); // segurar carro e carga
// preenche apolice basica return a;
return a; }
} public void carregar() {...}
... ...
} } 215
Como reduzir tangling e scattering?
1. Criar subclasse que implemente package veiculos;
recursos, sobreponha mtodos, etc. public class VeiculoCarga
extends Veiculo {
Problema: classes cliente tm que ser public void abastecer() {
alteradas para que saibam como criar a super.abastecer()
nova subclasse: + diesel;
}
VeiculoCarga v = }
// new VeiculoCarga();
new VeiculoCarga2();
2. Design patterns como
package veiculos.versao2;
factory method resolveriam o public class VeiculoCarga2
problema extends veiculos.VeiculoCarga {
public void abastecer() {
VeiculoCarga v = super.abastecer() + diesel;
VeiculoCarga.create(); Logger.log(nome() +
mas sua interface precisaria }
" abastecido com diesel");

ser planejada antes! public Apolice segurar() {...}


} 216
Soluo: Aspect-Oriented Programming
AOP divide interesses em dois grupos
Componentes: quando interesse encapsulvel em unidades
OO (classe, objeto, mtodo, procedimento).
Aspectos: interesses que no so representados como
componentes mas representar propriedades que interferem no
seu funcionamento ou estrutura.
Aspectos so interesses ortogonais
Costurados ao cdigo principal durante compilao ou
execuo (depende da implementao)
Weaver
Aplicao
Classes
Interesses do
domnio
Aspectos Join
Points
217
Soluo: Subject-Oriented Programming

Sujeitos (subjects) so abstraes diferentes de um mesmo conceito


dentro de um domnio especfico
Coloridos Desenhveis Mveis Mveis.Vlidos

Crculo Crculo Crculo simples-


Crculo valida coor-
colorir() desenhar() mover() mente move mover() denadas antes
a figura de mover

Para implementar a aplicao, sujeitos so compostos gerando um


objeto
Composio
Regras definem forma como os
sujeitos sero compostos Crculo
Pode-se trabalhar com conceitos colorir()
desenhar() valida coor-
simples (domain-specific) mover() denadas antes
de mover

218
Soluo: MDSoC: HyperSpaces
Representao de unidades de software em mltiplas dimenses de
interesse
Eixos representam dimenses de interesse
Pontos nos eixos representam interesses
Unidades de software so representadas no espao
Hyperslices
Recurso
Encapsulam interesses
Cor Crculo Retangulo Triangulo
colorir() colorir() colorir() Hypermodule
Movimento Crculo Retangulo Triangulo Conjunto de hyperslices
mover() mover() mover() e relacionamentos de
Crculo Retangulo Triangulo integrao (informam
mover() mover() mover() como hyperslices se
Classe
relacionam entre si)
Circulo Retngulo Tringulo
Validao
Neste modelo, aspecto
apenas mais uma dimenso de
... interesse
Aspecto Outras dimenses
de interesse 219
Uso de aspectos

Antes Depois

Cliente Cliente Isto feito usando


wildcards sem introduzir
cdigo no objeto
interface
Objeto
interface
ObjetoImpl
Objeto
ObjetoImpl
bm.start()
mtodo() {
bm.start(); mtodo()
corpo do mtodo Proxy
bm.stop(); bm.stop()
} mtodo()

220
Concluses
Neste minicurso, introduzimos diversos padres
usados em aplicaes OO
Padres clssicos GoF, que descrevem solues para
problemas comuns, elaborados
Padres GRASP, que descrevem aplicao de princpios OO
Padres e prticas emergentes como injeo de
dependncias (aplicao de uma prtica GRASP) e
aspectos (extenso do OO)
Aprenda a usar os padres clssicos e encurte o
tempo para ganhar tornar-se um programador
experiente!
Vrios outros padres existem e sero inventados
Alguns sobrevivero por muito tempo, outros no
Catalogue suas solues e crie seus prprios padres!
221
Fontes

[1][Metsker] Steven John Metsker, Design Patterns Java Workbook.


Addison-Wesley, 2002,
[2][GoF] Erich Gamma et al. Design Patterns: Elements of
Reusable Object-oriented Software. Addison-Wesley, 1994
[3] James W. Cooper. The Design Patterns Java Companion.
http://www.patterndepot.com/put/8/JavaPatterns.htm
[4][Larman] Craig Larman, Applying UML and Patterns, 2nd.
Edition, Prentice-Hall, 2002
[5][EJ] Joshua Bloch, Effective Java Programming Guide, Addison-
Wesley, 2001
[6][JMM FAQ] Jeremy Manson and Brian Goetz, JSR 133 (Java
Memory Model) FAQ, Feb 2004

222
Curso J930: Design Patterns
Verso 2.1

www.argonavis.com.br

2003, 2005, Helder da Rocha


(helder.darocha@gmail.com)

Você também pode gostar