AJUDAM A DEIXER O SISTEMA INDEPENDENTE DE COMO SEUS OBJETOS SÃO CRIADOS, COMPOSTOS E REPRESENTADOS
SÃO DOIS TIPOS:
PADRÕES DE CRIAÇÃO VIA CLASSES
USAM HERANÇA PARA VARIAR A CLASSE QUE É INSTANCIADA
EXEMPLO: FACTORY METHOD
PADRÕES DE CRIAÇÃO VIA OBJETOS
DELAGAM A INSTANCIAÇÃO PARA OUTRO OBJETO
EXEMPLO: ABSTRACT FACTORY
TAIS PADRÕES SÃO IMPORTANTES À MEDIDA QUE COMPOSIÇÃO É USADA MAIS QUE HERANÇA PARA ESTENDER FUNCIONALIDADE
EM VEZ DE CODIFICAR UM COMPORTAMENTO ESTATICAMENTE, DEFINIMOS PEQUENOS COMPORTAMENTOS PADRÃO E USAMOS COMPOSIÇÃO PARA DEFINIR COMPORTAMENTOS MAIS COMPLEXOS
OS PADRÕES DE CRIAÇÃO DISCUTEM TEMAS RECORRENTES:
ELES ENCAPSULAM O CONHECIMENTO DAS CLASSES CONCRETAS QUE SÃO INSTANCIADAS
LEMBRE QUE PREFERIMOS NOS "AMARRAR" A INTERFACES (VIA INTERFACE OU CLASSES ABSTRATAS) DO QUE A CLASSES CONCRETAS
ISSO PROMOVE A FLEXIBILIDADE DE MUDANÇA
ELES ESCONDEM COMO INSTÂNCIAS DAS CLASSES CONCRETAS SÃO INSTANCIADAS
USAREMOS A CONSTRUÇÃO DE LABIRINTOS PARA UM JOGO VIA COMPUTADOR PARA MOSTRAR ALGUNS PADRÕES DE CRIAÇÃO
IGNORAREMOS MUITOS DETALHES DO LABIRINTO (O QUE PODE ESTAR NO LABIRINTO, OS JOGADORES, ETC.)
FOCO NA CRIAÇÃO DOS LABIRINTOS
UM LABIRINTO É UM CONJUNTO DE SALAS
UMA SALA CONHECE SEUS QUATRO VIZINHOS
VIZINHOS PODEM SER OUTRA SALA, UMA PAREDE OU UMA PORTA PARA OUTRA SALA
AS CLASSES IMPORTANTES SÃO Sala, Porta E Parede
SÓ TRATAREMOS AS PARTES DAS CLASSES QUE INTERESSAM PARA A CRIAÇÃO DO LABIRINTO
O DIAGRAMA DE CLASSES SEGUE ABAIXO
EXERCÍCIO PARA CASA: REDESENHAR O DIAGRAMA COM INTERFACES
UM DIAGRAMA DE OBJETOS SEGUE PARA UM PEQUENO LABIRINTO
CADA SALA TEM QUATRO VIZINHOS
USAMOS NORTE, SUL, LESTE, OESTE PARA REFERENCIÁ-LOS
A CLASSE ElementoDoLabirinto É A CLASSE ABSTRATA COMUM PARA TODOS OS COMPONENTES DE UM LABIRINTO
TEM UM MÉTODO Entra CUJO SIGNIFICADO DEPENDE ONDE ESTÁ ENTRANDO
SE FOR UMA SALA, A LOCALIZAÇÃO DO JOGADOR MUDA
SE FOR UMA PORTA ABERTA, VOCÊ VAI PARA OUTRA SALA, CASO CONTRÁRIO SE MACHUCA
SE FOR UMA PAREDE, VOCÊ SE MACHUCA
abstract class ElementoDeLabirinto { public abstract void entra(); }
EXEMPLO: SE VOCÊ ESTIVER NUMA SALA E QUISER IMPLEMENTAR A OPERAÇÃO "VÁ PARA O LESTE", O JOGO DETERMINA QUAL ElementoDoLabirinto ESTÁ DO LADO LESTE E CHAMA Entra() DESTE OBJETO
A MÉTODO Entra DA SUBCLASSE ESPECÍFICA DETERMINA O QUE OCORRE
NUM JOGO REAL, Entra PODERIA ACEITAR O OBJETO JOGADOR COMO PARÂMETRO
Sala É A SUBCLASSE CONCRETA DE ElementoDoLabirinto QUE DEFINE AS RELAÇÕES CHAVE ENTRE OBJETOS
MANTÉM REFERÊNCIAS PARA 4 OUTROS ElementoDoLabirinto
ARMAZENA UM NÚMERO DE SALA PARA INDENTIFICAR AS SALAS DO LABIRINTO
class Sala extends ElementoDeLabirinto { private ElementoDeVizinho[] vizinhos = new ElementoDeVizinho[4]; private int númeroDaSala; public void Sala( int númeroDaSala ) { ... } public void entra() { ... } public ElementoDeLabirinto getVizinho( int direção ) { ... } public void setVizinho( int direção, ElementoDeLabirinto vizinho ) { ... } } class Parede extends ElementoDeLabirinto { public void Parede() { ... } public void entra() { ... } } class Porta extends ElementoDeLabirinto { private Sala sala1, sala2; private boolean estáAberta; public void Porta(ElementoDeLabirinto sala1, ElementoDeLabirinto sala2 ) { ... } public void entra() { ... } public Sala salaDoOutroLado( Sala sala ) { ... } }
TAMBÉM PRECISAMOS DE UM Labirinto PARA REPRESENTAR UMA COLEÇÃO DE SALAS
A CLASSE Labirinto PODE LOCALIZAR UMA SALA DADO SEU NÚMERO COM O MÉTODO getSala()
class Labirinto { private Vector salas = new Vector(); public void Labirinto() { ... } public void adicionaSala( Sala sala ) { ... } public Sala getSala( int númeroDaSala ) { ... } }
TAMBÉM DEFINIMOS UMA CLASSE Jogo QUE CRIA O LABIRINTO
UMA FORMA SIMPLES DE CRIAR UM LABIRINTO É DE CRIAR OS COMPONENTES, ADICIONÁ-LOS AO LABIRINTO E INTERCONECTÁ-LOS
EXEMPLO DA CRIAÇÃO DE UM LABIRINTO COM 2 SALAS E UMA PORTA ENTRE ELAS
class Jogo { ... public Labirinto criaLabirinto() { Labirinto umLabirinto = new Labirinto(); Sala sala1 = new Sala(1); Sala sala2 = new Sala(2); Porta aPorta = new Porta( sala1, sala2 ); umLabirinto.adicionaSala( sala1 ); umLabirinto.adicionaSala( sala2 ); sala1.setVizinho( NORTE, new Parede() ); sala1.setVizinho( LESTE, aPorta ); sala1.setVizinho( SUL, new Parede() ); sala1.setVizinho( OESTE, new Parede() ); sala2.setVizinho( NORTE, new Parede() ); sala2.setVizinho( LESTE, new Parede() ); sala2.setVizinho( SUL, new Parede() ); sala2.setVizinho( OESTE, aPorta ); return umLabirinto; } ... }
O PROBLEMA DESTA SOLUÇÃO É SUA INFLEXIBILIDADE
EM PARTICULAR, VEREMOS COMO MUDAR O PROJETO PARA CRIAR DIFERENTES TIPOS DE LABIRINTOS
LABIRINTOS ENCANTADOS
COM PORTAS TRAVADAS QUE PRECISAM DE UM ENCANTAMENTO PARA ABRIR
SALAS CONTENDO ENCANTAMENTOS QUE PODEM SER APANHADOS
LABIRINTOS PERIGOSOS
SALAS COM BOMBAS QUE PODEM SER EXPLODIDAS PARA DANIFICAR AS PAREDES (E TALVEZ O JOGADOR!)
COMO MUDAR criaLabirinto PARA FACILMENTE CRIAR ESTES NOVOS TIPOS DE LABIRINTOS?
O MAIOR PROBLEMA É QUE A SOLUÇÃO ATUAL NOS FORÇA A COLOCAR EM CÓDIGO AS CLASSES CONCRETAS QUE SERÃO INSTANCIADAS
USAREMOS PADRÕES DE CRIAÇÃO PARA TORNAR O PROJETO MAIS FLEXÍVEL