Escolar Documentos
Profissional Documentos
Cultura Documentos
2-Padres de criao
Estes padres abstraem o processo de instanciao. Ajudam a tornar o sistema
independente de como seus objetos so criados, compostos e representados.
2.1-O padro abstract factory (fbrica abstrata)
Problema tpico : Seja uma classe cliente que utiliza um conjunto de classes
atravs de seus mtodos. Suponha que cada uma destas classes deva trabalhar
em ambientes distintos,devendo ter, portanto, verses diferentes para cada um
destes ambientes. A questo : como fazer com que o cliente possa utilizar
alternativamente estas verses, sem que a forma como as classes so acessadas
sofra alteraes em funo destas verses?
FabricaAbstrata
CriarProdutoA()
CriarProdutoB()
FabricaConcret
a1
CriarProdutoA()
CriarProdutoB()
FabricaConcret
a2
CriarProdutoA()
CriarProdutoB()
Cliente
ProdutoAbstratoA
ProdutoA2
ProdutoA1
ProdutoAbstratoB
ProdutoB2
ProdutoB1
exemplifica
outro
ProdutoConcreto
denominada
mtodo
abstrato
criarBotao()
que
instancia
um
//Implementao
//BotaoComum
do
mtodo
abstrato
criarBotao()
criado
que
por
"
instancia
um
super("Nova GUI");
RotuloAbstrato rotulo = fabrica.createLabel();
BotaoAbstrato botao = fabrica.createButton("OK");
botao.addActionListener(new myActionListener(this));
JPanel panel = new JPanel();
panel.add(rotulo);
panel.add(botao);
this.getContentPane().add(panel);
this.pack();
this.setVisible(true);
this.addWindowListener(new myWindowListener(this));
}
private class myWindowListener extends WindowAdapter {
Display display = null;
protected myWindowListener(Display display) {
super();
this.display = display;
}
public void windowClosing(WindowEvent e) {
display.setVisible(false);
}
}
private class myActionListener implements ActionListener {
Display display;
protected myActionListener(Display display) {
super();
this.display = display;
}
public void actionPerformed(ActionEvent e) {
display.setVisible(false);
}
}
}
//Classe "driver" que executa e testa o padro
public class Main
{
//Declarar e instanciar as respectivas Fbricas
private static FabricaAbstrata factory1 = new FabricaComum();
private static FabricaAbstrata factory2 = new FabricaRebuscada();
//Instncia factory Recebe a instncia ser utilizada. Default: Fbrica
//comum
interface,
detalhes
de
implementao
so
ser
panel.add(factoryButton1);
panel.add(factoryButton2);
panel.add(create);
return panel;
}
//Executa este "driver"
public static void main(String[] args)
{
JFrame frame = new JFrame("Padro Fbrica Abstrata");
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {System.exit(0);}
});
frame.getContentPane().add(createGUI());
frame.pack();
frame.setVisible(true);
}
}
Construtora.
Diretora: a classe responsvel pela construo do objeto, invocando os
mtodos definidos na classe Construtora.
Produto: constitui as diversas verses do objeto complexo a ser construda.
Exemplos de aplicao:
-Construo de documentos complexos, constitudos de vrias partes, que
devem ser formatados de diversas maneiras (formato Word, HTML ou RTF, por
exemplo).
-Um buffer de impresso deve ter suas partes formatadas para diversos tipos de
impressoras. Criam-se classes ConstrutoraConcreta especializadas para cada
impressora.
Diretora
Construir()
Construtora
ConstruirParte()
Produto
}
class Documento
String aut,
String cont)
//Inicializo
//parmetro
objeto
complexo,
passando
suas
partes
como
Problema tpico: Suponha que uma determinada classe utiliza diversos tipos
de objetos. Mas no ponto em que utiliza estes objetos, ela no pode determinar
a classe de tais objetos. Como fazer com que esta classe possa utilizar estes
objetos independentemente da classe qual pertenam?
Soluo: Criar uma classe abstrata que contenha um factory method, que a
interface pela qual classes derivadas criam os objetos especficos. A classe base
implementa um mtodo que acessa a criao de tais objetos atravs da interface
do factory method. Na Figura 3 abaixo temos:
Criadora: Classe abstrata que declara um factory method abstrato, utilizado por
um mtodo (operao) que utiliza mltiplos tipos de objetos. Este factory
method sempre retorna uma instncia de um tipo de objeto e especializado
nas classes filhas (CriadoraConcreto)
Produto: Constitui uma classe abstrata que prov uma interface comum de
objetos a serem criados pelo factory method.
ProdutoConcreto: Especializa a interface definida em Produto.
Produto
Criadora
FactoryMethod()
Operacao()
produto=Fact
oryMethod
ProdutoConcreto
CriadoraConcret
a
FactoryMethod()
return new
ProdutoConcreto
DocumentoHTML).
//Classe abstrata
comum //e HTML
documento,
que
ser
especializada
em
dois
tipos:
String aut,
String cont){
String aut,
String cont){
String aut,
String aut,
String
aut,
cont);
System.out.println(doc.getTitulo());
System.out.println(doc.getAutor());
System.out.println(doc.getConteudo());
}
}
//Especializa a classe CriadoraDocumento para criar documentos comuns
public class CriadoraDocComum extends CriadoraDocumento {
//Especializa o factory method criarDocumento para que ele retorne um
//DocumentoComum
public
cont) {
Documento
criarDocumento(String
tit,
String
aut,
String
Documento
criarDocumento(String
tit,
String
aut,
String
execuo
do
exemplo.Deve
exibir
qualquer
tipo
de
seno,
if (args[0].equals("a")){
cri = criadcomum;
}
else {
cri = criadhtml;
}
//Uma nica chamada para qualquer que seja o documento a exibir:
cri.mostrarDocumento("Padro Builder","Pasteur O.M. Jr.",
"Contedo do documento");
}
}
Singleton
static InstanciaUnica
Dados
static Instancia()
Operacao()
ObterDados()
Instancia retorna
InstanciaUnica
garantir
class Main {
TelaSingleton T1 = TelaSingleton.Instancia();
T1.imprimir("T1.marc");
//Declaro novo dispositivo e imprimo. A instancia retornada a mesma:
//T1=T2, o que verificado pelas mensagens idnticas que so impressas
// via atributo marc do singleton.
TelaSingleton T2 = TelaSingleton.Instancia();
T2.imprimir("T2.marc");
}
}
2.5-O padro
Prototype (Prottipo)
Cliente
Operacao()
Prototipo
clone()
p=prototype.clone()
PrototipoCo
ncreto1
clone()
PrototipoCo
ncreto2
clone()
Exemplos de utilizao:
-Apesar de semelhante ao abstractFactory, este padro permite a instncia de
novas classes em tempo de execuo. Por exemplo, uma aplicao que permita
ao usurio exibir documentos, pode dar ao mesmo o recurso de inserir novos
tipos de documentos e exibi-los sem necessidade de recompilao de cdigo.
-Uma ferramenta CASE que trabalhe com frameworks de projeto define
prottipos para os mesmos, que sero clonados quando o cliente deles
necessitar.
String aut,
String
DocumentoComum (){
String aut,
String cont){
}
//Especializao de Documento: cria documento com formatao HTML
class DocumentoHTML extends Documento{
public
}
DocumentoHTML (){
}
class CriadoraDocumento {
//Classe cliente responsvel pela clonagem dos prottipos atravs da
// operao mostrarDocumento()
//atributo que vai conter o prottipo a ser clonado
private Documento documentoprototipo;
//Construtor
recebe
documentoprototipo
prottipo
aloca
ao
atributo
String aut,
String
3-Padres estruturais
Os padres estruturais esto relacionados a como classes e objetos so
compostos de forma a gerar estruturas maiores e mais complexas.
3.1- O padro adaptador (adapter)
Objetivo: Converter a interface de uma classe em outra, permitindo que classes
com interfaces incompatveis possam trabalhar em conjunto.
Problema tpico: Suponha que uma aplicao utilize um recurso de uma classe
especfica A. Este recurso acessado via mtodos da classe A. Entretanto,
descobriu-se no mercado uma nova alternativa para realizar as atribuies da
classe A, que possui mtodos de acesso completamente diferentes dos de A. A
questo : como introduzir esta nova classe na aplicao, sem alterar a interface
de acesso na aplicao, ou ainda, como permitir que novas classes possam ser
acessadas pela aplicao sem modificar esta interface de acesso?
Soluo: Criar uma classe abstrata comum para a classe A e a nova alternativa,
que ter sua interface acessada pelo cliente. Esta classe ser particularizada
para a classe A e para a classe alternativa e denominada adaptadora. Na
Figura 6 temos:
Alvo
Requisicao()
Adaptada
RequisicaoEspecifica()
Adaptadora
Requisicao()
adptada.RequisicaoEspecifica
-Uma aplicao utiliza uma interface comum para imprimir, que adaptada por
meio de subclasses adaptadoras a qualquer tipo de impressora.
*/
return txt;
}
}
class Botao extends JButton{
/* Interface da classe Botao deve
Componente */
/*
Chama
RequisicaoEspecifica
Requisicao
*
(inserircomponente) */
(inserirtexto()),
adaptando-o
panel.add(new JLabel(tex.inserirtexto()));
return panel;
}
}
class BotaoComponenteAdapter extends Componente {
/* Classe adaptadora, que faz a adaptao da interface de Botao
interface de Componente */
private Botao bot;
public BotaoComponenteAdapter(Botao bot) {
this.bot = bot;
if (panel == null) {panel = new JPanel();}
}
/*Implementacao do mtodo Requisicao */
public JPanel inserircomponente() {
/*
Chama
RequisicaoEspecifica
Requisicao
*
(inserircomponente) */
(inserirbotao()),
adaptando-o
panel.add(bot.inserirbotao() );
return panel;
}
}
Abstracao
Operacao()
Acessa
ImplOperacao
AbstracaoRefinada
Implementador
aConcretaA
ImplOperacao()
Implementador
aConcreta B
ImplOperacao()
Exemplos de utilizao:
-Suponha um objeto janela que pode ter diversos tipos de estruturao (como
caixa, como janela modal, como MDI, etc). Suponha que esta janela tenha
implementaes particularizadas para ambientes especficos, por exemplo, para
ambiente Linux e Windows. Podemos criar uma abstrao da classe janela e
particulariz-la para os seus diversos tipos possveis. Criamos tambm uma
classe de implementao de janelas, que ser particularizada para as
implementaes em Linux e Windows.
-Documentos de diversos tipos (por exemplo, artigo, carta, tutorial, etc) tm
uma abstrao comum e podem ter diversas implementaes para formatos
diferentes (por exemplo, rtf, doc, HTML, etc).
Uma Implementao em Java:
Este exemplo tem uma classe Abstracao chamada Documento, particularizada em
dois tipos: DocumentoArtigo e DocumentoTutorial. A classe Documento tem 3
mtodos
Operacao():
imprimirtitulo(),imprimirautor()
e
imprimirconteudo()
que acessam as operaes bsicas ImplOperacao()
chamadas
imprimircabecalho(),
imprimirtexto()
e
imprimirfinal()
definidas na interface ImplementacaoDocumento e implementadas de duas
formas: para documento HTML (ImplementacaoDocHTML) e documento comum
(ImplementacaoDocComum).
abstract class Documento {
/* Classe Abstracao, base para a criao de documentos de
* diversos tipos
*/
protected String titulo;
protected String autor;
protected String conteudo;
private ImplementacaoDocumento impdoc;
public Documento(ImplementacaoDocumento
aut, String cont){
this.impdoc = impdoc;
titulo = tit;
autor = aut;
conteudo = cont;
impdoc,String
tit,
String
}
/* A seguir temos trs operaes utilizadas para criao dos tipos de
documento */
public String imprimirtitulo(){
da
classe
de
}
public String imprimirautor(){
/*
Utiliza
operao
primitiva
imprimirtexto()
implementao
ImplementacaoDocumento */
da
classe
de
return impdoc.imprimirtexto(autor);
}
public String imprimirconteudo(){
/* Utiliza operaes primitivas imprimirtexto() e imprimirfinal()
interface
de implementao
ImplementacaoDocumento */
return impdoc.imprimirtexto(conteudo)+impdoc.imprimirfinal();
da
impdoc,String
tit,
}
public String
imprimir(){
String
resumo
imprimirconteudo().substring(1,conteudo.length()/5);
return
imprimirtitulo()+imprimirautor()
imprimirconteudo();
}
}
class DocumentoTutorial extends Documento {
=
+
resumo
impdoc,String
tit,
interface ImplementacaoDocumento{
/* Interface para a criao dos diversos tipos de implementao de
documentos */
/*Operaes primitivas de implementao de documentos. Correspondem ao
mtodo
ImplemOperacao() */
public String imprimircabecalho(String texto);
public String imprimirtexto(String texto);
public String imprimirfinal();
}
class ImplementacaoDocComum implements ImplementacaoDocumento{
/* Primeira ImplementadoraConcreta: criao de documentos comuns, sem
formatao */
public String imprimircabecalho(String texto){
return texto +
"\n";
}
public String imprimirtexto(String texto){
return texto +
"\n";
}
public String imprimirfinal(){
return " ";
}
class ImplementacaoDocHTML implements ImplementacaoDocumento{
/* Segunda ImplementadoraConcreta: criao de documentos com formatao
HTML*/
public String imprimircabecalho(String texto){
return
"<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN'>"+
"<html>"+
"<head>"+
"<title>"+
texto+"</title>"+
"<meta http-equiv='Content-Type' content='text/html; charset=iso-88591'>"+
"</head>"+
"<body>"+
"<div align='center'>"+
"<p><font size='7'><strong>"+
texto+ "<br>"+
"</strong><strong></strong></font><strong><br>"+
"<br>";
}
public String imprimirtexto(String texto){
return
"<p align='left'>"+
texto+"</p>";
}
public String imprimirfinal(){
return
"</div>"+
"</body>" +
"</html>";
}
}
}
Soluo: Criar uma classe que ser a me da classe qual o objeto pertence e
de toda e qualquer responsabilidade adicional, que ser chamada de classe
decoradora. As responsabilidades adicionais sero derivadas desta classe. Estas
faro referncia classe do objeto, adicionando o comportamento desejado. Na
Figura 8 temos:
ComportamentoAdicionado.
Componente
Operacao()
Componente
Concreto
Operacao()
Decoradora
Operacao()
DecoradoraConcreta
Operacao()
ComportamentoAdicionado()
Invocar Operacao() de
ComponenteConcreto
*/
*/
/* Retorna a instncia de um
*/
/* Retorna a instncia de um
public
Rotulo(String titulo){
comp = new JLabel(titulo);
}
}
abstrata
da
qual
sero
especializadas
todas
as
}
class DecoradoraBorda extends Decoradora {
/* Esta classe acrescenta uma borda ao componente visual */
/*Mtodo desenhar() (operacao()) especializado para colocar a borda */
public JComponent desenhar(){
componente.comp= componente.desenhar();
return colocarborda();
}
/*
Mtodo
que
desenha
ComportamentoAdicionado) */
borda
ao
componente,
mtodo
return componente.comp;
}
public DecoradoraBorda(ComponenteVisual componente){
super(componente);
}
}
class DecoradoraFundo extends Decoradora {
/* Esta classe acrescenta cor de fundo ao componente visual */
private Color cor;
/*Mtodo desenhar() (operacao()) especializado para colocar a cor de
fundo */
public JComponent desenhar(){
componente.comp = componente.desenhar();
return modificarfundo();
}
/* Mtodo que insere a cor
ComportamentoAdicionado)*/
de
fundo
ao
componente
mtodo
new
e)
/* Adiciono o botao */
panel.add(botaofundo.desenhar());
/* Adiciono o rotulo */
panel.add(rotfundo.desenhar());
frame.getContentPane().add(panel);
frame.pack();
frame.setVisible(true);
}
}
Problema tpico:
objetos que represeta, ou seja, o estado que comum a todos eles. Dependendo
do contexto em que utilizado, o flyweight assume estados que variam com
este contexto, os chamados estados extrnsecos. Estes estados no so
compartilhados e os clientes que utilizam os flyweights detem a
responsabilidade por pass-los a eles. Esta estrutura proporciona considervel
economia de memria. Na Figura 9 temos:
Retorna um flyweight, se
existir ou cria um
flyweight e retorna
FabricaFlyweights
RetornarFlyweight(chave)
Cliente
Flyweight
FlyweightConcreto
EstadoIntrinseco
Operacao(EstadoExtrinseco)
public LetraHTMLFlyweight(char c) {
this.c = c;
}
//Parmetro tamanho o estado extrnseco do flyweight
//Mtodo exibir mostra o estado intrnseco do flyweight, utilizando o
//estado extrnseco tamanho.
public void exibir(int tamanho) {
System.out.print("<font
size='"+Integer.toString(tamanho)+"'>"+c);
}
}
/* Fbrica de flyweights */
class FabricaLetra {
//Armazena o estado intrnseco do flyweight em uma tabela hash
private Hashtable tabela = new Hashtable();
/* Mtodo RetornaFlywight que retorna
instncia do flyweight */
que
cria
os
flyweights
armazena
new
estados
/*
texto[9] = (LetraHTMLFlyweight)fl.PegarLetraFlyweight('i');
tamanholetra[9]= 4;
texto[10] = (LetraHTMLFlyweight)fl.PegarLetraFlyweight('p');
tamanholetra[10]= 7;
texto[11] = (LetraHTMLFlyweight)fl.PegarLetraFlyweight('e');
tamanholetra[11]= 3;
texto[12] = (LetraHTMLFlyweight)fl.PegarLetraFlyweight('d');
tamanholetra[12]= 7;
texto[13] = (LetraHTMLFlyweight)fl.PegarLetraFlyweight('o');
tamanholetra[13]= 5;
/* Exibe cada flyweight do
extrnseco como parmetro. */
texto
paralelepipedo
passando
estado
objeto do tipo AssuntoReal somente vai ser instanciado quando for necessrio e
isto ser feito por Proxy.
Assunto
Requisicao()
AssuntoReal
Requisicao()
Proxy
Requisicao()
acessa operacao
Requisicao de
AssuntoReal
um texto na tela*/
}
else {return textoreal.retornartamanho();}
}
/* Construtor do proxy inicializado apenas com o tamanho do texto a
ser manipulado */
/* Repare que ele no instancia ainda o TextoReal */
public TextoProxy(int tambuf) {
tamanhobuffer = tambuf;
}
public void Imprimir(String texto) {
/* Cria a instncia de TextoReal, se ela j no existir */
if
(textoreal
TextoReal(tamanhobuffer);
==
null)
textoreal
nenhuma
instncia
new
/*Imprime o texto */
textoreal.Imprimir(texto);
}
}
public class TesteProxy {
/*Classe cliente */
public static void main (String[] args) {
/* Criar a instncia do Proxy */
Texto txtproxy = new TextoProxy(15);
/*Manipulo a instncia
texto foi criada */
do
Proxy.
Neste
ponto,
de
Fachada: Classe que passa a ser a interface de Cliente. atravs dela que
Cliente acessa os mtodos das classe Classe1, Classe2, Classen. Suas operaes
instanciam estas classes e invocam as operaes das mesmas.
Classe1, Classe2, Classen: so as classes que provem as operaes utilizadas
por Cliente atravs da classe Fachada.
Cliente: Acessa somente os mtodos da classe Fachada, ao invs do mtodos
das classes Classe1, Classe2, Classen.
Operaes de Fachada
instanciam objetos das
classes 1,2..n,
invocando seus mtodos
Classe1
Oper11()
Oper12()
Oper1n()
Fachada
Operacao1()
Operacao2()
Classe2
Oper21()
Oper22()
Oper2n()
Cliente
Classen
Opern1()
Opern2()
Opernn()
}
class Transformadora {
/*Classe que transforma o texto para maisculas e minsculas ou coloca
somente a primeira letra em maiscula*/
public static String TransformarMaiuscula(String s){
return s.toUpperCase();
}
public static String TransformarMinuscula(String s){
return s.toLowerCase();
}
public static String TransformarPrimeiraMaiuscula(String s){
String st;
st = s.toLowerCase();
st= st.substring(0,1).toUpperCase()+ st.substring(1);
return st;
}
}
class TextoHTMLFacade {
/*Classe de fachada, que reduz a necessidade de acesso aos mtodos das
classes acima */
public String RetornaCabecalho(String titulo){
String cabe =
"<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN'>"+
"<html>"+
"<head>"+
"<title>"+titulo+"</title>"+
"<meta http-equiv='Content-Type' content='text/html; charset=iso-88591'>"+
"</head>"+"<body>";
return cabe;
}
public String RetornaFinal(){
return "</body>";
}
public
titulo;
= Transformadora.TransformarMaiuscula(texto);
= Formatadora.AdicionarNegrito(titulo);
= Formatadora.AdicionarCentralizar(titulo);
titulo;
}
public
item;
Transformadora.TransformarPrimeiraMaiuscula(texto);
Formatadora.AjustarTamanho(item,2);
Formatadora.AdicionarNegrito(item);
Formatadora.AdicionarItalico(item);
Formatadora.AdicionarEdentacao(item);
item;
}
public String RetornaTextoComum (String texto) {
/*Formata um texto comum dentro de um documento HTML*/
String txt;
txt = Transformadora.TransformarPrimeiraMaiuscula(texto);
txt = Formatadora.AdicionarEdentacao(txt);
txt = Formatadora.AdicionarEdentacao(txt);
txt = Formatadora.AjustarTamanho(txt,1);
return txt;
}
}
class ExemploDocumentoHTML {
/* Classe cliente, criada para demonstrar a criao de um documento
HTML acessando apenas os mtodos da classe facade */
e exibe */
Componente.
Cliente
Componente
Operacao()
AdicionarComponente()
RemoverComponente()
RetornarFilho()
Folha
Operacao()
Composite
Operacao()
AdicionarComponente()
RemoverComponente()
RetornarFilho()
Para cada filho chamar
Operacao()
public
4-Padres Comportamentais
Esto relacionados
ao comportamento dos objetos, ou seja, com o
estabelecimento de padres de comunicao entre eles.
Sucessor
Cliente
Manipulador
ManipularRequisicao()
ManipuladorConcreto1
ManipularRequisicao()
ManipuladorConcreto2
ManipularRequisicao()
javax.swing.*;
javax.swing.JFrame;
java.awt.event.WindowEvent;
java.awt.event.WindowAdapter;
java.awt.event.*;
interface Manipulador {
/* Classe Manipulador */
public void manipularRequisicao(String nomemanip);
}
class Botao extends JButton implements Manipulador {
/*Classe ManipuladorConcreto Botao invoca um sucessor caso no seja
o responsvel pela requisio */
if (nomemanip.equals(this.getName())){
/* Se for, finaliza exibindo uma mensagem */
System.out.println("Requisio recebida e FINALIZADA por :
"+this.getName() );
}
else {
/* Seno, passa a requisio para seu sucessor */
System.out.println("Requisio recebida por : "+this.getName()+ " e
enviada para "+sucessor.getClass().getName());
sucessor.manipularRequisicao(nomemanip);
}
}
}
class Painel extends JPanel implements Manipulador {
/*Segunda classe manipuladora, Painel, anloga Botao */
protected Manipulador sucessor;
public Painel(Manipulador sucessor,String nome) {
super();
this.setName(nome);
this.sucessor = sucessor;
}
public void manipularRequisicao(String nomemanip) {
if (nomemanip.equals(this.getName())){
System.out.println("Requisio recebida e FINALIZADA por :
"+this.getName());
}
else {
System.out.println("Requisio recebida por : "+this.getName()+ " e
enviada para "+sucessor.getClass().getName());
sucessor.manipularRequisicao(nomemanip);
}
}
}
class Quadro extends JFrame implements Manipulador {
/*Terceira classe manipuladora, Quadro, anloga Botao e Painel */
protected Manipulador sucessor;
REFERNCIAS
[GAM98} GAMMA, E, et al. Design Patterns-Elements of Reusable ObjectOriented Software 1a Edio, Addison Wesley, 1998.
[KIK02] KIKZALES, Gregor. HANNEMAN, Jan Design Patterns Implementations.
ca.ubc.cs.spl.patterns, 2002.