VAMOS ADICIONAR UMA BORDA À ÁREA DE EDIÇÃO
VAMOS ADICIONAR BARRAS DE ROLAGEM
NÃO VAMOS USAR HERANÇA PARA ADICIONAR ESTE EMBELEZAMENTO
NÃO PODERÍAMOS MUDAR O EMBELEZAMENTO EM TEMPO DE EXECUÇÃO
PARA N TIPOS DE EMBELEZAMENTO, PRECISARÍAMOS DE 2N-1 SUBCLASSES PARA TER TODAS AS COMBINAÇÕES
TEREMOS MAIS FLEXIBILIDADE SE OUTROS OBJETOS DA UI NÃO SOUBEREM QUE ESTÁ HAVENDO EMBELEZAMENTO!
INCLUSÃO TRANSPARENTE
USAR COMPOSIÇÃO EM VEZ DE HERANÇA EVITA OS PROBLEMAS MENCIONADOS MAS QUAIS OBJETOS DEVEM PARTICIPAR DA COMPOSIÇÃO?
O EMBELEZAMENTO EM SI SERÁ UM OBJETO (DIGAMOS UMA INSTÂNCIA DA CLASSE Borda)
ISSO NOS DÁ DOIS OBJETOS PARA FAZER A COMPOSIÇÃO: ElementoDeDocumento E Borda
DEVEMOS DECIDIR AGORA QUE VAI COMPOR QUEM
A Borda PODE CONTER O ElementoDeDocumento
FAZ SENTIDO JÁ QUE A BORDA ENGLOBA O ElementoDeDocumento NA TELA
O ElementoDeDocumento PODE CONTER A Borda
ISSO IMPLICA EM MUDAR A CLASSE ElementoDeDocumento PARA QUE ELA CONHEÇA A Borda
USAREMOS A PRIMEIRA ESCOLHA DE FORMA A MANTER O CÓDIGO QUE TRATA BORDAS INTEIRAMENTE NA CLASSE Borda SEM MEXER NAS OUTRAS CLASSES
COMO CONSTRUIR A CLASSE Borda?
O FATO DA BORDA TER UMA APARÊNCIA NA TELA SUGERE QUE ELA DEVERIA SER UMA SUBCLASSE DE ElementoDeDocumento
TEM UM OUTRO MOTIVO MAIS FORTE AINDA DE FAZER ISSO: CLIENTES TRATAM OBJETOS ElementoDeDocumento E NÃO DEVERIAM SABER SE UM ElementoDeDocumento TEM UMA BORDA OU NÃO!
CLIENTES DEVEM TRATAR ElementoDeDocumento UNIFORMEMENTE
SE UM CLIENTE MANDA UM ElementoDeDocumento SEM BORDA SE DESENHAR NÃO VAI APARECER BORDA, CASO CONTRÁRIO, VAI APARECER BORDA, MAS O CLIENTE NÃO SABE
ISSO IMPLICA QUE A Borda TEM A MESMA INTERFACE QUE ElementoDeDocumento
FAZEMOS Borda UMA SUBCLASSE DE ElementoDeDocumento PARA GARANTIR ESTE RELACIONAMENTO
ESTE CONCEITO CHAMA-SE "INCLUSÃO TRANSPARENTE"
COMPOSIÇÃO COM UM ÚNICO FILHO; E
INTERFACES COMPATÍVEIS
CLIENTES NÃO SABEM SE ESTÃO TRATANDO DO OBJETO ORIGINAL (ElementoDeDocumento) OU DO SEU INCLUIDOR (Borda)
O INCLUIDOR DELEGA AS OPERAÇÕES PARA O OBJETO INCLUÍDO, MAS AUMENTA O COMPORTAMENTO FAZENDO SEU TRABALHO ANTES OU DEPOIS DA DELEGAÇÃO DA OPERAÇÃO
A CLASSE MonoElementoDeDocumento
DEFINIMOS UMA SUBCLASSE DE ElementoDeDocumento CHAMADA MonoElementoDeDocumento
MonoElementoDeDocumento É UMA CLASSE ABSTRATA PARA TODOS OS ElementoDeDocumento DE EMBELEZAMENTO
MonoElementoDeDocumento ARMAZENA UMA REFERÊNCIA A UM ElementoDeDocumento E ENCAMINHA TODOS OS PEDIDOS PARA ELE (FORWARDING)
MonoElementoDeDocumento ARMAZENA UMA REFERÊNCIA A UM ÚNICO ElementoDeDocumento (DAÍ "MONO") E ENCAMINHA TODOS OS PEDIDOS PARA ELE (FORWARDING)
ISSO FAZ COM QUE MonoElementoDeDocumento SEJA COMPLETAMENTE TRANSPARENTE AOS CLIENTES
A CLASSE MonoElementoDeDocumento VAI REIMPLEMENTAR PELO MENOS UM DOS MÉTODOS DE ElementoDeDocumento PARA FAZER SEU TRABALHO
EXEMPLO: Borda REDEFINE O MÉTODO draw:
public class Borda extends MonoElementoDeDocumento { ... public void draw( Panel p) { super.draw( p ); drawBorda( p ); } ... }
OBSERVE QUE Borda ESTENDE O MÉTODO DO PAI PARA DESENHAR A BORDA
JÁ QUE CHAMA O MÉTODO DO PAI ANTES DE FAZER SEU TRABALHO
A CLASSE ROLADOR TAMBÉM É UM EMBELEZAMENTO
ELA DESENHA SEU COMPONENTE EM POSIÇÕES DIFERENTES DEPENDENDO DE DUAS BARRAS DE ROLAGEM
ELA ADICIONA AS BARRAS DE ROLAGEM COMO EMBELEZAMENTO
AO DESENHAR SEU COMPONENTE, Rolador PEDE AO SISTEMA GRÁFICO PARA FAZER "CLIPPING" DO COMPONENTE NOS LIMITES APROPRIADOS
AS PARTES FORA DOS LIMITES NÃO APARECERÃO
AGORA, COMO ADICIONAR UMA Borda E UM Rolador?
COMPOMOS OS ElementosAFormatar DENTRO DE UM Rolador E ESTE DENTRO DE UMA Borda
SE COMPUSÉSSEMOS A Borda DENTRO DO Rolador, A BORDA SERIA ROLADA TAMBÉM
SE ISSO FOR O COMPORTAMENTO DESEJADO, ESSA ORDEM DEVE SER USADA
A ESTRUTURA DE OBJETOS APARECE ABAIXO
OBSERVE QUE OS EMBELEZADORES COMPÕEM UM ÚNICO COMPONENTE
SE TENTÁSSEMOS EMBELEZAR MAIS DE UMA COISA DE CADA VEZ, TERÍAMOS QUE MISTURAR VÁRIOS TIPOS DE ElementoDeDocumento COM EMBELEZADORES
TERÍAMOS EMBELEZAMENTO DE LINHA, EMBELEZAMENTO DE COLUNA, ETC.
O JEITO QUE FIZEMOS PARECE MELHOR
ESTE PADRÃO CHAMA-SE "DECORATOR"
EMBELEZAMENTO USANDO INCLUSÃO TRANSPARENTE
OBSERVE QUE O EMBELEZAMENTO PODE, NA REALIDADE, SER QUALQUER ADIÇÃO DE RESPONSABILIDADES
EX. EMBELEZA UMA ÁRVORE DE SINTAXE COM AÇÕES SEMÂNTICAS
EX. EMBELEZA UMA MÁQUINA DE ESTADOS FINITOS COM NOVAS TRANSIÇÕES
O PADRÃO DECORATOR
OBJETIVO
ADICIONAR RESPONSABILIDADES DINAMICAMENTE A UM OBJETO
DECORADORES PROVÊEM UMA ALTERNATIVA FLEXÍVEL À HERANÇA PARA ESTENDER FUNCIONALIDADE
PERMITEM ADICIONAR RESPONSABILIDADES A UM OBJETO E NÃO A UMA CLASSE INTEIRA
TAMBÉM CHAMADO DE WRAPPER
QUANDO USAR O PADRÃO DECORATOR?
PARA ADICIONAR RESPONSABILIDADES DINAMICAMENTE A OBJETOS INDIVIDUAIS E TRANSPARENTEMENTE (SEM AFETAR OUTROS OBJETOS)
QUANDO HÁ RESPONSABILIDADES QUE PODEM SER RETIRADAS
QUANDO HERANÇA GERARIA UMA EXPLOSÃO DE SUBCLASSES
QUANDO A HERANÇA SERIA UMA BOA ALTERNATIVA MAS A DEFINIÇÃO DA CLASSE ESTÁ ESCONDIDA OU NÃO DISPONÍVEL PARA HERANÇA
ESTRUTURA GENÉRICA
EXERCÍCIO PARA CASA: REDESENHE O DIAGRAMA ACIMA USANDO INTERFACES
PARTICIPANTES
Componente (EX. ElementoDeDocumento)
DEFINE A INTERFACE DE OBJETOS QUE PODEM TER RESPONSABILIDADES ADICIONADAS DINAMICAMENTE
ComponenteConcreto (EX. ElementosAFormatar)
DEFINE UM OBJETO AO QUAL SE PODE ADICIONAR RESPONSABILIDADES ADICIONAIS
Decorador (EX. MonoElementoDeDocumento)
MANTÉM UMA REFERÊNCIA A UM OBJETO Componente E DEFINE UMA INTERFACE IGUAL À DO Componente
DecoradorConcreto
ADICIONA RESPONSABILIDADES AO Componente
COLABORAÇÕES ENTRE OBJETOS
O DECORADOR ENCAMINHA PEDIDOS AO COMPONENTE
PODE OPCIONALMENTE ADICIONAR OPERAÇÕES ANTES OU DEPOIS DESTE ENCAMINHAMENTO
CONSEQUÊNCIAS DO USO DO PADRÃO DECORATOR
MAIS FLEXÍVEL DO QUE HERANÇA ESTÁTICA
PODE ADICIONAR RESPONSABILIDADES DINAMICAMENTE
PODE ATÉ ADICIONAR RESPONSABILIDADES DUAS VEZES! (EX. BORDA DUPLA)
EVITA CLASSES COM FEATURES DEMAIS NO TOPO DA HIERARQUIA
EM VEZ DE TENTAR PREVER TODOS OS FEATURES NUMA CLASSE COMPLEXA E CUSTOMIZÁVEL, PERMITE DEFINIR CLASSES SIMPLES E ADICIONAR FUNCIONALIDADE DE FORMA INCREMENTAL COM OBJETOS DECORADORES
DESTA FORMA, AS APLICAÇÕES NÃO TÊM QUE PAGAR PELOS FEATURES QUE NÃO USAM
PONTO NEGATIVO: OS DECORADOR E O OBJETO INCLUSO NÃO SÃO IDÊNTICOS
PORTANTO, CUIDADO COM A IDENTIDADE DE OBJETOS: UM DECORADOR ADICONADO A UM OBJETO VAI MUDAR O OBJETO COM O QUAL O CLIENTE LIDA
PONTO NEGATIVO: MUITOS PEQUENOS OBJETOS
FÁCIL DE CUSTOMIZAR POR PROGRAMADORES QUE ENTENDEM O PROJETO MAS PODE SER DIFÍCIL ENTENDER E DEPURAR
CONSIDERAÇÕES DE IMPLEMENTAÇÃO
A INTERFACE DO DECORADOR DEVE SER IGUAL À INTERFACE DO OBJETO SENDO DECORADO
SE TIVER QUE ADICIONAR UMA ÚNICA RESPONSABILIDADE, PODE REMOVER O DECORADOR ABSTRATO
NESTE CASO, O DECORADOR CONCRETO PODE TRATAR DO FORWARDING PARA O COMPONENTE INCLUSO
MANTENDO COMPONENTES ENXUTOS
A CLASSE Componente DEVE SER MANTIDA ENXUTA E OS DADOS SER DEFINIDOS NOS COMPONENTES CONCRETOS
CASO CONTRÁRIO, OS DECORADORES (QUE HERDAM DE Componente) FICAM "PESADOS"
DECORATOR VERSUS STRATEGY
DECORATOR MUDA A "PELE" DE UM OBJETO
STRATEGY MUDA AS ENTRANHAS
STRATEGY É MELHOR QUANDO A CLASSE Componente É PESADA
NESTE CASO, O DECORADOR SERIA PESADO DEMAIS
COM STRATEGY, PARTE DO COMPORTAMENTO DE Componente É REPASSADO PARA OUTRO OBJETO (QUE IMPLEMENTA UM ALGORITMO)
O COMPONENTE "SABE" DA EXISTÊNCIA DO(S) OBJETO(S) DE ESTRATÉGIA MAS NÃO SABE DA EXISTÊNCIA DE DECORADORES
EXEMPLO: BORDAS COM STRATEGY
O Componente PODE MANDAR UM OBJETO Borda (QUE ELE CONHECE) DESENHAR A BORDA
O Componente PODE MANTER UMA LISTA DE OBJETOS DE ESTRATÉGIA PARA FAZER VÁRIAS COISAS, O QUE É EQUIVALENTE A TER DECORADORES RECURSIVOS
NESTE CASO, O OBJETO Borda ENCAPSULA A ESTRATÉGIA DE DESENHAR UMA BORDA
VER A FIGURA ABAIXO