Padrões de Projeto de Software Unidade 2 – Padrões GoF Luiz Leão – [email protected] http://www.luizleao.com Padrões de Projetos de Software Conteúdo Programático • PADRÕES CRIAÇÃO • – – – – – • Abstract Factory Builder Factory Method Prototype Singleton. PADRÕES ESTRUTURAIS – – – – – – – Adapter Bridge Composite Decorator Façade Flyweight Proxy PADRÕES COMPORTAMENTAIS – Chain of Responsibility – Command – Interpreter – Iterator – Mediator – Memento – Observer – State – Strategy – Template Method – Visitor Unidade 2 – Padrões GoF Padrões de Projetos de Software Catálogo de Padrões (GoF) • Um padrão encerra o conhecimento de uma pessoa muito experiente em um determinado assunto de uma forma que este conhecimento pode ser transmitido para outras pessoas menos experientes. • Outras ciências (p.ex. química) e engenharias possuem catálogos de soluções. • Desde 1995, o desenvolvimento de software passou a ter o seu primeiro catálogo de soluções para projeto de software: o livro do GoF (Gang of Four). Unidade 2 – Padrões GoF Padrões de Projetos de Software Catálogo de Padrões (GoF) • E. Gamma and R. Helm and R. Johnson and J. Vlissides. Design Patterns 5 - Elements of Reusable Object-Oriented Software. Addison-Wesley, 1995. Unidade 2 – Padrões GoF Padrões de Projetos de Software Catálogo de Padrões (GoF) • Passamos a ter um vocabulário comum para conversar sobre projetos de software. • Soluções que não tinham nome passam a ter nome. • Ao invés de discutirmos um sistema em termos de pilhas, filas, árvores, passamos a falar de 6 coisas de muito mais alto nível como Fábricas, Fachadas, Observador, Estratégia, etc. Unidade 2 – Padrões GoF Padrões de Projetos de Software Catálogo de Padrões (GoF) • A maioria dos autores eram entusiastas de Smalltalk, principalmente o Ralph Johnson. • Mas acabaram baseando o livro em C++ para que o impacto junto à comunidade de C fosse maior. • E o impacto foi enorme, o livro vendeu centenas de milhares de cópias. Unidade 2 – Padrões GoF Padrões de Projetos de Software Catálogo de Padrões (GoF) • PADRÕES CRIAÇÃO – – – – – Abstract Factory Builder Factory Method Prototype Singleton. • PADRÕES ESTRUTURAIS – – – – – – – Adapter Bridge Composite Decorator Façade Flyweight Proxy • PADRÕES COMPORTAMENTAIS – – – – – – – – – – – Chain of Responsibility Command Interpreter Iterator Mediator Memento Observer State Strategy Template Method Visitor Unidade 2 – Padrões GoF Padrões de Projetos de Software Classificação, segundo GoF Unidade 2 – Padrões GoF Padrões de Projetos de Software Classificação, segundo Metsker Unidade 2 – Padrões GoF Padrões de Projetos de Software Catálogo de Padrões (GoF) Como os padrões resolvem os problemas? • Encontrando objetos apropriados: a decomposição é influenciada por fatores tais como encapsulamento, granularidade, dependências, flexibilidade, desempenho, evolução, reutilização, etc. Frequentemente surgem classes que não possuem correspondentes no negócio • Determinando a granularidade do objeto • Especificando as interfaces dos objetos: um tipo denota uma interface em particular. Um objeto pode ter muitos tipos e diferentes objetos podem ter um mesmo tipo. Ligação dinâmica e polimorfismo Unidade 2 – Padrões GoF Padrões de Projetos de Software Catálogo de Padrões (GoF) Como os padrões resolvem os problemas? • Especificando a implementação de objetos: – – – – – – Notação para classe. Instanciação (seta tracejada). Herança de classe (implementação). Classes abstratas (em itálico). Classes mix-in. Diferença entre a classe (implementação) e o tipo (interface) do objeto Unidade 2 – Padrões GoF Padrões de Projetos de Software Catálogo de Padrões (GoF) • Todo padrão inclui o mínimo: – – – – – Nome Problema Solução Consequências Exemplo Unidade 2 – Padrões GoF Padrões de Projetos de Software Formato dos Padrões (GoF) • Nome (inclui número da página): Um bom nome é essencial para que o padrão tenha aceitação da comunidade • Objetivo / Intenção • Motivação: Um cenário realista mostrando o problema e a necessidade da solução • Aplicabilidade: Como reconhecer as situações nas quais o padrão é aplicável Unidade 2 – Padrões GoF Padrões de Projetos de Software Formato dos Padrões (GoF) • Estrutura: Uma representação gráfica da estrutura de classes do padrão (usando OMT91) em, às vezes, diagramas de interação (Booch 94) • Participantes: As classes e objetos que participam e quais são suas responsabilidades • Colaborações: Como os participantes colaboram para exercer as suas responsabilidades Unidade 2 – Padrões GoF Padrões de Projetos de Software Formato dos Padrões (GoF) • Conseqüências: Vantagens e desvantagens, trade-offs • Implementação: Com quais detalhes devemos nos preocupar quando implementamos o padrão, entre eles, aspectos específicos de cada linguagem • Exemplo de Código: No caso do GoF, em C++ (a maioria) ou Smalltalk. Implementaremos em Java Unidade 2 – Padrões GoF Padrões de Projetos de Software Formato dos Padrões (GoF) • Usos Conhecidos: Exemplos de sistemas reais de domínios diferentes onde o padrão é utilizado • Padrões Relacionados: Quais outros padrões devem ser usados em conjunto com esse quais padrões são similares a este, quais são as diferenças Unidade 2 – Padrões GoF Padrões de Projetos de Software Formato dos Padrões (GoF) Exemplo: • Alguns padrões são utilizados em conjunto. Ex: Composite com Iterator ou Visitor • Alguns outros são alternativos. Ex: Prototype ou Abstract Factory • Alguns padrões apresentam projeto similar, embora tenham diferentes propósitos. Ex: Composite e Decorator Unidade 2 – Padrões GoF Padrões de Projetos de Software Tipos de Padrões de Projeto • Padrões de Criação: Estão relacionados com a forma que os objetos são criados • Padrões Estruturais: Tratam das associações entre classes e objetos • Padrões Comportamentais: Tratam das interações e divisões de responsabilidades entre as classes ou objetos. Unidade 2 – Padrões GoF Padrões de Criação Padrões de Projetos de Software Padrões de Criação • Os padrões de criação tem como intenção principal abstrair o processo de criação de objetos, ou seja, a sua instanciação. • Desta maneira o sistema não precisa se preocupar com questões sobre, como o objeto é criado, como é composto, qual a sua representação real. Unidade 2 – Padrões GoF Padrões de Projetos de Software Padrões de Criação • Quando se diz que o sistema não precisa se preocupar com a instanciação do objeto quer dizer que, se ocorrer alguma mudança neste ponto, o sistema em geral não será afetado. • Isso é a famosa flexibilidade que os padrões de projeto buscam. Unidade 2 – Padrões GoF Padrões de Projetos de Software Padrões de Criação • Padrões de criação com escopo de classe vão utilizar herança para garantir que a flexibilidade. Por exemplo, o padrão Factory Method pode criar várias subclasses para criar o produto. • Já os padrões com escopo de Objeto, como o Prototype, delegam para um objeto (no caso o protótipo) a responsabilidade de instanciar novos objetos. Unidade 2 – Padrões GoF Padrões de Projetos de Software Padrões de Criação • • • • • Abstract Factory Builder Factory Method Prototype Singleton. Unidade 2 – Padrões GoF Padrões de Projetos de Software Abstract Factory • Intenção: – Prover uma interface para criação de famílias de objetos relacionados sem especificar sua classe concreta. Unidade 2 – Padrões GoF Padrões de Projetos de Software Abstract Factory • Motivação: – Considere uma aplicação com interface gráfica que é implementada para plataformas diferentes (Motif para UNIX e outros ambientes para Windows e MacOS). – As classes implementando os elementos gráficos não podem ser definidas estaticamente no código. Precisamos de um implementação diferente para cada ambiente. Até em um mesmo ambiente, gostaríamos de dar a opção ao usuário de implementa diferentes aparências (look-and-feels). Unidade 2 – Padrões GoF Padrões de Projetos de Software Abstract Factory • Motivação (Cont.): – Podemos solucionar este problema definindo uma classe abstrata para cada elemento gráfico e utilizando diferentes implementações para cada aparência ou para cada ambiente. – Ao invés de criarmos as classes concretas com o operador new, utilizamos uma Fábrica Abstrata para criar os objetos em tempo de execução. – O código cliente não sabe qual classe concreta utilizamos. Unidade 2 – Padrões GoF Padrões de Projetos de Software Abstract Factory • Aplicabilidade: Pode ser usado quando: – Um sistema deve ser independente da forma como seus produtos são criados e representados; – Um sistema deve poder lidar com uma família de vários produtos diferentes; – Você quer prover uma biblioteca de classes de produtos mas não quer revelar as suas implementações, quer revelar apenas suas interfaces. Unidade 2 – Padrões GoF Padrões de Projetos de Software Abstract Factory – Estrutura Unidade 2 – Padrões GoF Padrões de Projetos de Software Abstract Factory – Participantes • • • • AbstractFactory (WidgetFactory) ConcreteFactory (MotifWidgetFactory, WindowsWidgetFactory) AbstractProduct (Window, ScrollBar) ConcreteProduct (MotifWindow, MotifScrollBar, WindowsWindow, WindowsScrollBar) • Client - Usa apenas as interfaces declaradas pela AbstractFactory e pelas classes AbstratProduct Unidade 2 – Padrões GoF Padrões de Projetos de Software Abstract Factory – Colaborações • Normalmente, apenas uma instância de ConcreteFactory é criada em tempo de execução. • Esta instância cria objetos através das classes ConcreteProduct correspondentes a uma família de produtos. • Uma AbstractFactory deixa a criação de objetos para as suas subclasses ConcreteFactory. Unidade 2 – Padrões GoF Padrões de Projetos de Software Abstract Factory – Consequências • Isola as classes concretas dos clientes; • Facilita a troca de famílias de produtos (basta trocar uma linha do código pois a criação da fábrica concreta aparece em um único ponto do programa); • Promove a consistência de produtos (não há o perigo de misturar objetos de famílias diferentes); • Dificulta a criação de novos produtos • Ligeiramente diferentes (pois temos que modificar a fábrica abstrata e todas as fábricas concretas). Unidade 2 – Padrões GoF Padrões de Projetos de Software Abstract Factory – Implementação • Fábricas abstratas em geral são implementadas como Singleton. • Na fábrica abstrata, cria-se um método fábrica para cada tipo de produto. • Cada fábrica concreta implementa o código que cria os objetos de fato. Unidade 2 – Padrões GoF Padrões de Projetos de Software Abstract Factory – Implementação • Se tivermos muitas famílias de produtos, teríamos um excesso de classes "fábricas concretas". • Para resolver este problema, podemos usar o Prototype: criamos um dicionário mapeando tipos de produtos em instâncias prototípicas destes produtos. • Então, sempre que precisarmos criar um novo produto pedimos à sua instância prototípica que crie um clone (usando um método como clone() ou copy()). Unidade 2 – Padrões GoF Padrões de Projetos de Software Abstract Factory – Implementação • Em linguagens dinâmicas como Smalltalk onde classes são objetos de primeira classe, não precisamos guardar uma instância prototípica, guardamos uma referência para a própria classe e daí utilizamos o método new para construir as novas instâncias. Unidade 2 – Padrões GoF Padrões de Projetos de Software Abstract Factory – Usos Conhecidos • InterViews: Usa fábricas abstratas para encapsular diferentes tipos de aparências para sua interface gráfica • ET++: Usa fábricas abstratas para permitir a fácil portabilidade para diferentes ambientes de janelas (XWindows e SunView, por exemplo) • Sistema de captura e reprodução de vídeo feito na UIUC usa fábricas abstratas para permitir portabilidade entre diferentes placas de captura de vídeo. • Em linguagens dinâmicas como Smalltalk (e talvez em POO em geral) classes podem ser vistas como fábricas de objetos. Unidade 2 – Padrões GoF Padrões de Projetos de Software Abstract Factory – Exemplo Unidade 2 – Padrões GoF Padrões de Projetos de Software Abstract Factory – Código • WidgetFactory.java abstract class WidgetFactory { public static WidgetFactory obterFactory() { if(Configuracao.obterInterfaceGraficaAtual() == Configuracao.MotifWidget) { return new MotifWidgetFactory(); } else { return new QtWidgetFactory(); } } public abstract Botao criarBotao(); } Unidade 2 – Padrões GoF Padrões de Projetos de Software Abstract Factory – Código • MotifWidgetFactory.java class MotifWidgetFactory extends WidgetFactory { public Botao criarBotao() { return new BotaoMotif(); } } Unidade 2 – Padrões GoF Padrões de Projetos de Software Abstract Factory – Código • QtWidgetFactory.java class QtWidgetFactory extends WidgetFactory { public Botao criarBotao() { return new BotaoQt(); } } Unidade 2 – Padrões GoF Padrões de Projetos de Software Abstract Factory – Código • Botao.java abstract class Botao { public abstract void desenhar(); } Unidade 2 – Padrões GoF Padrões de Projetos de Software Abstract Factory – Código • BotaoMotif.java class BotaoMotif extends Botao { public void desenhar(){ System.out.println("Eu sou um botao Motif!"); } } Unidade 2 – Padrões GoF Padrões de Projetos de Software Abstract Factory – Código • BotaoQt.java class BotaoQt extends Botao { public void desenhar(){ System.out.println("Eu sou um botao Qt!"); } } Unidade 2 – Padrões GoF Padrões de Projetos de Software Abstract Factory – Código • Client.java (Classe Executável) public class Cliente { public static void main(String[] args) { WidgetFactory factory = WidgetFactory.obterFactory(); Botao botao = factory.criarBotao(); botao.desenhar(); } } Unidade 2 – Padrões GoF Padrões de Projetos de Software Abstract Factory – Padrões Relacionados • Factory Method • Prototype • Singleton Unidade 2 – Padrões GoF Padrões de Projetos de Software Factory Method • Intenção: – Definir uma interface (ou classe abstrata) para a criar um objeto; – Permitir a decisão de que implementações ou subclasses devem ser instanciadas; – Deixa uma classe deferir instanciação para subclasses – Factory Method é conhecido como Virtual Constructor; Unidade 2 – Padrões GoF Padrões de Projetos de Software Factory Method • Motivação: – Os frameworks usam classes abstratas para definir e manter relacionamentos entre objetos; • Considere um framework para aplicações que podem apresentar múltiplos documentos pra usuários; • Duas abstrações chaves: – Application (aplicação) e Document (documento); Unidade 2 – Padrões GoF Padrões de Projetos de Software Factory Method • Problema: – A classe Application não pode prever a subclasse de Document a ser instanciada; • Ou seja, ela não tem conhecimento sobre o tipo do Document apenas sabe quando deve ser criado; Unidade 2 – Padrões GoF Padrões de Projetos de Software Factory Method • Solução: – Usar o Factory Method que encapsula o conhecimento sobre a subclasse de Document que deve ser criado movendo este conhecimento para fora do framework; Unidade 2 – Padrões GoF Padrões de Projetos de Software Factory Method Unidade 2 – Padrões GoF Padrões de Projetos de Software Factory Method Unidade 2 – Padrões GoF Padrões de Projetos de Software Factory Method Unidade 2 – Padrões GoF Padrões de Projetos de Software Factory Method Unidade 2 – Padrões GoF Padrões de Projetos de Software Factory Method Unidade 2 – Padrões GoF Padrões de Projetos de Software Factory Method – Aplicabilidade • Usar o padrão quando: – Quando uma classe não pode antecipar ou conhecer a classe dos objetos que deve criar; – Quando uma classe quer que suas subclasses especifiquem os objetos que criam; – Quando classes delegam responsabilidade à alguma das várias subclasses ajudantes, e deseja-se localizar qual é a subclasse ajudante acessada. Unidade 2 – Padrões GoF Padrões de Projetos de Software Factory Method – Estrutura Unidade 2 – Padrões GoF Padrões de Projetos de Software Factory Method – Estrutura Unidade 2 – Padrões GoF Padrões de Projetos de Software Factory Method – Estrutura Unidade 2 – Padrões GoF Padrões de Projetos de Software Factory Method – Estrutura Unidade 2 – Padrões GoF Padrões de Projetos de Software Factory Method – Estrutura Unidade 2 – Padrões GoF Padrões de Projetos de Software Factory Method • Colaborações para projeto: – Uso da classe Creator que utiliza subclasses para definir o seu método FactoryMethod (método de fabricação) de maneira que retorne um objeto ou instância do ConcretProduct apropriado; Unidade 2 – Padrões GoF Padrões de Projetos de Software Factory Method – Consequências • Vantagens: – Elimina a necessidade de acoplar classes específicas para aplicação em nível de código; – Na programação, se lida apenas com a interface Product para conhecer os métodos e atributos de uma forma genérica, o que permite manipular as subclasses ou implementações de maneira particular (ConcreteProduct). – Fornece ganchos para classes • Cria objetos através do método FactoryMethod (métodos de fabricação); • FactoryMethod possibilita as subclasses um gancho para fornecer um versão estendida de um objeto; Unidade 2 – Padrões GoF Padrões de Projetos de Software Factory Method – Consequências • Vantagens: – Conecta hierarquias de classes paralelas • Ocorrem quando uma classe delega alguma das suas responsabilidades para uma classe separada; Unidade 2 – Padrões GoF Padrões de Projetos de Software Factory Method – Consequências • Desvantagens: – Os clientes podem ter que fornecer subclasses da classe Creator somente para criar um objeto ConcreteProduct em particular; Unidade 2 – Padrões GoF Padrões de Projetos de Software Factory Method – Consequências • Implementação (dicas) : – Duas principais variações do padrão Factory Method: • O Creator é uma classe abstrata e não fornece uma implementação para método de fabricação (factory method) que ela declara; • O Creator é uma classe concreta e fornece uma implementação por omissão para o método de fabricação (factory method); Unidade 2 – Padrões GoF Padrões de Projetos de Software Factory Method – Consequências • Implementação (dicas) : – Método de fabricação (factory method) parametrizados: • O método de fabricação recebe um parâmetro que identifica o objeto a ser criado; Unidade 2 – Padrões GoF Padrões de Projetos de Software Factory Method – Exemplo Unidade 2 – Padrões GoF Padrões de Projetos de Software Factory Method – Código • Aplicacao.java abstract class Aplicacao { private Documento doc; //Abstração do Factory Method abstract Documento criaDocumento(); void novoDocumento() { this.doc = this.criaDocumento(); } void abrirDocumento() { this.doc.abrir(); } } Unidade 2 – Padrões GoF Padrões de Projetos de Software Factory Method – Código • MinhaAplicacao.java class MinhaAplicacao extends Aplicacao { /** * Uma implementação do Factory Method. Este método é * especializado na criação de documentos do tipo * MeuDocumento */ @Override Documento criaDocumento() { return new MeuDocumento(); } } Unidade 2 – Padrões GoF Padrões de Projetos de Software Factory Method – Código • Documento.java abstract class Documento { void abrir() { System.out.println("Documento:Abrir documento!"); } void fechar() { System.out.println("Documento:Fechar documento!"); } void gravar() { System.out.println("Documento:Gravar documento!"); } } Unidade 2 – Padrões GoF Padrões de Projetos de Software Factory Method – Código • MeuDocumento.java class MeuDocumento extends Documento { private String word = "Word"; private String excel = "Excel"; String getWord() { return this.word; } String getExcel() { return this.excel; } } Unidade 2 – Padrões GoF Padrões de Projetos de Software Factory Method – Código • FactoyMethodTest.java public class FactoyMethodTest { public static void main(String[] args) { MinhaAplicacao aplicacao = new MinhaAplicacao(); Documento docu = aplicacao.criaDocumento(); docu.abrir(); MeuDocumento documento = new MeuDocumento(); System.out.println("Documento: " + documento.getWord()); } } Unidade 2 – Padrões GoF Padrões de Projetos de Software Factory Method – Padrões Relacionados • Abstract Factory • Template Method • Prototype Unidade 2 – Padrões GoF Padrões de Projetos de Software Factory Method – Código • Análise do código: – O que podemos melhorar e há alguma coisa errada com código? – Falta alguma classe ser implementada? Unidade 2 – Padrões GoF Padrões de Projetos de Software Factory Method – Exercício 1. Implemente a aplicação mostrada na figura abaixo usando Factory Method para criar os objetos. 1. Crie um objeto construtor para cada tipo de objeto (XXXFactory para criar figuras do tipo XXX) 2. Utilize a fachada Figura, onde os construtores são guardados, e um método estático que seleciona o construtor desejado com uma chave. Unidade 2 – Padrões GoF Padrões de Projetos de Software Singleton Unidade 2 – Padrões GoF Padrões de Projetos de Software Singleton • Intenção: – Garantir que uma classe tenha somente uma instância e fornecer um ponto global de acesso para a mesma; Unidade 2 – Padrões GoF Padrões de Projetos de Software Singleton • Motivação: – Em muitas aplicações necessitamos garantir a ocorrência de apenas uma instância de classes, pois tais objetos podem fazer uso de recursos cuja utilização deve ser exclusiva, ou porque se deseja que os demais elementos do sistema compartilhem um único objeto particular. Ex.: Um filtro digital terá somente um conversor A/D; Um sistema de contabilidades será dedicado somente a uma companhia; Unidade 2 – Padrões GoF Padrões de Projetos de Software Singleton • Problema: – Como garantir que uma classe tenha somente um instância e que essa instância seja facilmente acessível? – Uma variável global torna um objeto acessível, mas não impede você de instanciar múltiplos objetos; Unidade 2 – Padrões GoF Padrões de Projetos de Software Singleton • Solução: – Tornar a própria classe responsável por manter o controle da sua única instancia; – A classe pode garantir que nenhuma outra instância seja criada e fornecer um meio para acessar sua única instância; – Padrão Singleton; Unidade 2 – Padrões GoF Padrões de Projetos de Software Singleton – Aplicabilidade • Usar o padrão quando: – Deve haver uma única instância de uma classe e esta deve ser acessada a partir de um ponto de acesso bem conhecido. – A instância única deve ser extensível através de subclasses, possibilitando aos clientes usar instância estendida sem alterar o seu código; Unidade 2 – Padrões GoF Padrões de Projetos de Software Singleton – Estrutura Unidade 2 – Padrões GoF Padrões de Projetos de Software Singleton – Estrutura Unidade 2 – Padrões GoF Padrões de Projetos de Software Singleton • Colaborações para projeto: – Os clientes acessam uma instância Singleton unicamente pela operação Instance do Singleton; Unidade 2 – Padrões GoF Padrões de Projetos de Software Singleton – Consequências • Vantagens: – Acesso controlado à instância única; – O Singleton tem controle sobre como e quando clientes acessam a instância; – Espaço de nomes reduzido; • O Singleton é melhor que variáveis globais, já que as “globais” podem ser encapsuladas na instância única, deixando um único nome externo visível; Unidade 2 – Padrões GoF Padrões de Projetos de Software Singleton – Consequências • Vantagens: – Permite refinamento de operações e de representação; • Várias classes Singleton (relacionadas ou não via herança) podem obedecer a mesma interface, permitindo que um Singleton particular seja escolhido para trabalhar com uma determinada aplicação em tempo de execução; – Mais flexível que métodos estáticos; Unidade 2 – Padrões GoF Padrões de Projetos de Software Singleton – Implementação (Dicas) • Garantir uma única instância; – Ocultando a operação que cria a instância usando um operação de classe (isto é, uma função-membro estática ou um método de classe); • Criar subclasses da classe Singleton; – A variável que referencia a instância do Singleton deve ser iniciada com uma instância da subclasse; • Retira-se a implementação da Instance da classe-mãe e colocá-la na subclasse; Unidade 2 – Padrões GoF Padrões de Projetos de Software Singleton – Implementação (Dicas) Unidade 2 – Padrões GoF Padrões de Projetos de Software Singleton – Implementação (Dicas) • Singleton.java public class Singleton { private static Singleton instance = new Singleton(); int x; String msg; private Singleton() { this.x = (int) (10 * Math.random()); this.msg = "-- A classe foi instanciada criando um Objeto Singleton.\n" + "\t # x inicializado com o valor inteiro: " + String.valueOf(this.x); System.out.println(this.msg); } public static synchronized Singleton getInstance() { if (instance == null) instance = new Singleton(); return instance; } } Unidade 2 – Padrões GoF Padrões de Projetos de Software Singleton – Implementação (Dicas) • SingletonTest.java public class SingletonTest { public static void main(String args[]) { Singleton concreteSing = null; concreteSing = concreteSing.getInstance(); } } Unidade 2 – Padrões GoF Padrões de Projetos de Software Builder Unidade 2 – Padrões GoF Padrões de Projetos de Software Builder • Intenção: – Propõe que o processo de construção de um objeto, quando complexo, seja separado da definição do objeto, para que possamos ter diferentes algoritmos de construção permitindo diferentes representações para o objeto. – Devemos lembrar desde já que Factory Method e Abstract Factory são padrões que trabalham na criação de objetos de uma família de classes, trabalhando intensamente com polimorfismo, enquanto o Builder tem o foco nos detalhes de construção de uma instância de objeto, que não necessariamente terá uma família de subclasses. Unidade 2 – Padrões GoF Padrões de Projetos de Software Builder – Estrutura • • • • Builder - Especifica a interface para criação de um objeto produto. ConcreteBuilder - São as implementações de Builder. Director - Classe que sabe o algoritmo de construção do objeto. Product - Representa o objeto-produto final. Unidade 2 – Padrões GoF Padrões de Projetos de Software Builder – Antipattern • O que é? – É um padrão de projeto de software que pode ser comumente usado mas é ineficiente e/ou contraprodutivo em prática Unidade 2 – Padrões GoF Padrões de Projetos de Software Builder – Antipattern • Imaginemos uma situação onde precisamos construir diferentes tipos de computadores com diferentes componentes: servidor, computador para games e computador básico. • Poderíamos criar métodos em classes aleatórias que criam os computadores porém as diferentes lógicas de criação do computador ficariam espalhadas pelo código. • O padrão Builder visa organizar justamente os processos de criação de objetos complexos. Unidade 2 – Padrões GoF Padrões de Projetos de Software Builder – Aplicação class builder2 ComputadorBuilder ComputadorDirector ~builder ~ builder: ComputadorBuilder + + ComputadorDirector(ComputadorBuilder) buildComputador() : Computador ComputadorBasicoBuilder + + + createComputador() : void addPlacaMae() : void addHardDisks() : void # computador: Computador + + + + createComputador() : void addPlacaMae() : void addHardDisks() : void getComputador() : Computador ComputadorGamesBuilder + + + createComputador() : void addPlacaMae() : void addHardDisks() : void Serv idorBuilder + + + createComputador() : void addPlacaMae() : void addHardDisks() : void Unidade 2 – Padrões GoF Padrões de Projetos de Software Builder – Exemplo • Conversor de Texto: Unidade 2 – Padrões GoF Padrões de Projetos de Software Builder – Exemplo • Conversor de Texto: – Neste exemplo, o método lerRTF() (classe LeitorRTF) percorre uma lista com os tokens encontrados no texto de entrada (formato RTF) e, para cada tipo de token, chama um método do objeto de tipoConversorTexto. – Dependendo do formato escolhido para o texto de destino, será escolhida uma implementação da classe ConversorTexto: ConversorPDF, ConversorTeX ou ConversorASC II. – Cada uma destas classes implementa os métodos de acordo com as características do formato relacionado. – A classe ConversorASCII não implementa os métodos converteParagrafo() e converteFonte() pois este formato (ASCII) não possui elementos de estilo. Unidade 2 – Padrões GoF Padrões de Projetos de Software Builder – Código • ConversorTexto.java abstract void void void } class ConversorTexto { converterCaractere(char c) {} converterParagrafo() {} converterFonte(Fonte f) {} Unidade 2 – Padrões GoF Padrões de Projetos de Software Builder – Código • ConversorPDF.java class ConversorPDF extends ConversorTexto { void converterCaractere(char c) { System.out.println("Caractere PDF"); } void converterParagrafo() { System.out.println("Paragrafo PDF"); } void converterFonte(Fonte f) { System.out.println("Fonte PDF"); } } Unidade 2 – Padrões GoF Padrões de Projetos de Software Builder – Código • ConversorTeX.java class ConversorTeX extends ConversorTexto { void converterCaractere(char c) { System.out.println("Caractere TeX"); } void converterParagrafo() { System.out.println("Paragrafo TeX"); } void converterFonte(Fonte f) { System.out.println("Fonte TeX"); } } Unidade 2 – Padrões GoF Padrões de Projetos de Software Builder – Código • ConversorASCII.java class ConversorASCII extends ConversorTexto { void converterCaractere(char c) { System.out.println("Caractere ASCII"); } } Unidade 2 – Padrões GoF Padrões de Projetos de Software Builder – Código • LeitorRTF.java class LeitorRTF { private ConversorTexto conversor; LeitorRTF(ConversorTexto c) { this.conversor = c; } public void lerRTF() { List<Token> tokens = obterTokensDoTexto(); for (Token t : tokens) { if (t.getTipo() == Token.Tipo.CARACTERE){ conversor.converterCaractere(t.getCaractere()); } if (t.getTipo() == Token.Tipo.PARAGRAFO) { conversor.converterParagrafo(); } if (t.getTipo() == Token.Tipo.FONTE) { conversor.converterFonte(t.getFonte()); } } } } Unidade 2 – Padrões GoF Padrões de Projetos de Software Builder – Código • Cliente.java public class Cliente { public static void main(String[] args) { ConversorTexto conversor; if (args[0].equals("pdf")) { conversor = new ConversorPDF(); } else if (args[0].equals("tex")) { conversor = new ConversorTeX(); } else { conversor = new ConversorASCII(); } LeitorRTF leitor = new LeitorRTF(conversor); leitor.lerRTF(); } } Unidade 2 – Padrões GoF Padrões de Projetos de Software Prototype • Apresentação: – Especifica os tipos de objetos a criar usando uma instância de protótipo, criando-os mediante cópia (ou clonagem) deste protótipo. – Esta operação é realizada sem que a aplicação saiba qual classe específica está sendo instanciada. Unidade 2 – Padrões GoF Padrões de Projetos de Software Prototype • Aplicabilidade: – Em situações nas quais deve-se criar instâncias de objetos a partir de hierarquias de classes complexas e quando a classe de um objeto é conhecida somente em tempo de execução são exemplos do uso deste padrão de projeto. Unidade 2 – Padrões GoF Padrões de Projetos de Software Prototype • Estrutura: Unidade 2 – Padrões GoF Padrões de Projetos de Software Prototype • Estrutura: – Prototype: Uma classe que declara uma interface para objetos capazes de clonar a si mesmo. – PrototypeConcreto(1,2,...): Implementação de um prototype; – Cliente: Cria um novo objeto através de um prototype que é capaz de clonar a si mesmo. Unidade 2 – Padrões GoF Padrões de Projetos de Software Prototype • Descrição: – A utilização deste padrão de projeto dá-se pela existência de uma classe base (ou interface) contendo a declaração do método clone() e, dependendo da implementação, mantém um coleção (na forma de um dicionário, por exemplo) de classes concretas derivadas da classe base (ou que implementem a interface). Unidade 2 – Padrões GoF Padrões de Projetos de Software Prototype • Exemplo na API Java: – Este padrão de projeto é a essência da especificação JavaBean. A interface java.lang.Cloneable existe para que classes a implementem, e, assim, atestem que podem ser clonadas, mediante a sobre-escrita do método clone(), disponível na classe java.lang.Object. Unidade 2 – Padrões GoF Padrões de Projetos de Software Prototype • Observações: – Eventualmente, padrões de projeto de criação competem entre si em uso. – Às vezes pode-se utilizar ou o padrão de projeto Prototype ou Abstract Factory. – Enquanto em outros casos, ambos são complementos um do outro. Unidade 2 – Padrões GoF Padrões de Projetos de Software Prototype • Padrões Relacionados – Abstract Factory, Composite e Decorator. Unidade 2 – Padrões GoF Padrões de Projetos de Software Prototype • Anti-Pattern – O uso deste padrão de projeto destina-se a criar cópias (clones) a partir de uma instância denominada protótipo. – Assim, o seu anti-pattern é a situação na qual toda vez que uma cópia de um determinado objeto é necessária sua criação deve ser realizada, comprometendo, possivelmente, o desempenho da aplicação e a quantidade de memória para comportar um número elevado de objetos. Unidade 2 – Padrões GoF Padrões de Projetos de Software Prototype • Exemplo: – Neste exemplo é mostrado uma hierarquia de classes representando documentos de formato ASCII e PDF que são criados através da classe Cliente. – A partir de duas instâncias prototípicas, ascii e pdf, o método criarDocumento cria clones de documentos de acordo com o tipo desejado. – A tarefa de realizar a criação da instância é implementada na classe Documento e herdada por suas classes filhas, ASCII ePDF. Unidade 2 – Padrões GoF Padrões de Projetos de Software Prototype • Exemplo: Unidade 2 – Padrões GoF Padrões de Projetos de Software Prototype - Código • Icloneable.java: public interface ICloneable { public void clone(); } Unidade 2 – Padrões GoF Padrões de Projetos de Software Prototype - Código • Documento.java: abstract class Documento implements ICloneable { protected Documento clone() { Object clone = null; try { clone = super.clone(); } catch (CloneNotSupportedException ex) { ex.printStackTrace(); } return (Documento) clone; } } Unidade 2 – Padrões GoF Padrões de Projetos de Software Prototype - Código • ASCII.java: class ASCII extends Documento { } Unidade 2 – Padrões GoF Padrões de Projetos de Software Prototype - Código • PDF.java: class PDF extends Documento { } Unidade 2 – Padrões GoF Padrões de Projetos de Software Prototype - Código • Cliente.java: class Cliente { static final int DOCUMENTO_TIPO_ASCII = 0; static final int DOCUMENTO_TIPO_PDF = 1; private Documento ascii = new ASCII(); private Documento pdf = new PDF(); public Documento criarDocumento(int tipo) { if (tipo == Cliente.DOCUMENTO_TIPO_ASCII) { return ascii.clone(); } else { return pdf.clone(); } } } Unidade 2 – Padrões GoF Padrões Estruturais Padrões de Projetos de Software Padrões Estruturais • Os padrões estruturais vão se preocupar em como as classes e objetos são compostos, ou seja, como é a sua estrutura. • O objetivo destes padrões e facilitar o design do sistema identificando maneiras de realizar o relacionamento entre as entidades, deixando o desenvolvedor livre desta preocupação. Unidade 2 – Padrões GoF Padrões de Projetos de Software Padrões Estruturais • Os padrões com escopo de classe utilizam a herança para compor implementações ou interfaces. • O padrão Adapter, por exemplo, pode definir uma nova interface para adaptar duas outras já existentes, assim uma nova classe é criada para adaptar uma interface a outra. Os padrões com escopo de objeto utilizam a composição de objetos para definir uma estrutura. • Por exemplo, o padrão Composite define (explicitamente) uma estrutura de hierárquica para classes primitivas e compostas em um objeto. Unidade 2 – Padrões GoF Padrões de Projetos de Software Padrões Estruturais • • • • • • • Adapter Bridge Composite Decorator Façade Flyweight Proxy Unidade 2 – Padrões GoF Padrões Comportamentais Padrões de Projetos de Software Padrões Comportamentais • Os padrões comportamentais atuam sobre como responsabilidades são atribuídas as entidades, ou seja, qual o comportamento das entidades. • Estes padrões facilitam a comunicação entre os objetos, distribuindo as responsabilidades e definindo a comunicação interna. Unidade 2 – Padrões GoF Padrões de Projetos de Software Padrões Comportamentais • Padrões com escopo de classe utilizam herança para realizar a distribuição do comportamento. • Um bom exemplo é o padrão Template Method, que fornece um algoritmo (comportamento) padrão e deixa as subclasses definirem alguns pontos da execução do algoritmo. • Já os padrões de objetos vão compor os objetos para definir a comunicação, como o padrão Mediator, que define um objeto que realiza a comunicação muitos-paramuitos. Unidade 2 – Padrões GoF Padrões de Projetos de Software Padrões Comportamentais • • • • • • • • • • • Chain of Responsibility Command Interpreter Iterator Mediator Memento Observer State Strategy Template Method Visitor Unidade 2 – Padrões GoF Padrões de Projetos de Software Chain of Responsibility Unidade 2 – Padrões GoF Padrões de Projetos de Software Chain of Responsibility • Apresentação: • Normalmente, este padrão de projeto é utilizado em situações nas quais se deseja que mais de um objeto possa tratar (manipular) um pedido (requisição), evitando o acoplamento entre o remetente de um pedido e o seu destinatário. • Assim, os objetos recebedores são encadeados e o pedido é passado por este encadeamento até que um objeto o trate. Unidade 2 – Padrões GoF Padrões de Projetos de Software Chain of Responsibility • Aplicabilidade: • Este padrão de projeto é comumente utilizando quando mais de um objeto é capaz de tratar um pedido e o mesmo não é conhecido antecipadamente. • O objeto tratador do pedido deve ser reconhecido automaticamente. • Um pedido deve ser tratado por um entre vários objetos sem que o objeto tratador seja especificado explicitamente. Unidade 2 – Padrões GoF Padrões de Projetos de Software Chain of Responsibility • Estrutura: Unidade 2 – Padrões GoF Padrões de Projetos de Software Chain of Responsibility • Estrutura: • Cada objeto no encadeamento (ConcreteHandlerA, ConcreteHandlerB) age como um tratador de pedidos e conhece seu sucessor. • Se um dado objeto é capaz de tratar o pedido ele o faz, caso contrário o pedido é passado ao próximo tratador no encadeamento de objetos. Unidade 2 – Padrões GoF Padrões de Projetos de Software Chain of Responsibility • Exemplo: • Uma aplicação de e-commerce precisa se comunicar com vários bancos diferentes para prover aos seus usuários mais possibilidades de pagamentos, atingindo assim um número maior de usuários e facilitando suas vidas. • Ao modelar uma forma de execução do pagamento, dado que precisamos selecionar um entre vários tipos de bancos, a primeira ideia que surge é utilizar uma estrutura de decisão para verificar, dado um parâmetro, qual o banco correto deve ser utilizado. Unidade 2 – Padrões GoF Padrões de Projetos de Software Chain of Responsibility • Exemplo: Unidade 2 – Padrões GoF Padrões de Projetos de Software Chain of Responsibility – Código • IDBancos.java: public enum IDBancos { bancoA, bancoB, bancoC, bancoD } Unidade 2 – Padrões GoF Padrões de Projetos de Software Chain of Responsibility – Código • BancoChain.java: public abstract class BancoChain { protected BancoChain next; protected IDBancos identificadorDoBanco; public BancoChain(IDBancos id) { next = null; identificadorDoBanco = id; } public void setNext(BancoChain forma) { if (next == null) { next = forma; } else { next.setNext(forma); } } } Unidade 2 – Padrões GoF Padrões de Projetos de Software Chain of Responsibility – Código • BancoChain.java: public void efetuarPagamento(IDBancos id) throws Exception { if (podeEfetuarPagamento(id)) { efetuaPagamento(); } else { if (next == null) { throw new Exception("banco não cadastrado"); } next.efetuarPagamento(id); } } private boolean podeEfetuarPagamento(IDBancos id) { if (identificadorDoBanco == id) { return true; } return false; } protected abstract void efetuaPagamento(); Unidade 2 – Padrões GoF Padrões de Projetos de Software Chain of Responsibility – Código • BancoA.java: public class BancoA extends BancoChain { public BancoA() { super(IDBancos.bancoA); } @Override protected void efetuaPagamento() { System.out.println("Pagamento efetuado no banco A"); } } Unidade 2 – Padrões GoF Padrões de Projetos de Software Chain of Responsibility – Código • Client.java: public class Client { public static void main(String[] args) { BancoChain bancos = new BancoA(); bancos.setNext(new BancoB()); bancos.setNext(new BancoC()); bancos.setNext(new BancoD()); try { bancos.efetuarPagamento(IDBancos.bancoC); bancos.efetuarPagamento(IDBancos.bancoD); bancos.efetuarPagamento(IDBancos.bancoA); bancos.efetuarPagamento(IDBancos.bancoB); } catch (Exception e) { e.printStackTrace(); } }} Unidade 2 – Padrões GoF Padrões de Projetos de Software Command Unidade 2 – Padrões GoF Padrões de Projetos de Software Command • Apresentação: • Este padrão de projeto representa comandos como objetos. • Isto possibilita realizar requisições a objetos sem o conhecimento de como a operação é executada ou o destinatário (receiver) da requisição. Unidade 2 – Padrões GoF Padrões de Projetos de Software Command • Aplicabilidade: • Objetos podem ser parametrizados pela ação a executar, como, por exemplo, uma opção de menu ou um botão em uma barra de ferramentas. • Opcionalmente, um comando pode especificar uma operação de desfazer (undo), permitindo reverter os efeitos no próprio comando. Assim, a interface Command deve declarar uma operação (método) – undo() – para realizar tal operação. Unidade 2 – Padrões GoF Padrões de Projetos de Software Command • Aplicabilidade: • Neste caso, as ações realizadas por execute() são armazenadas em uma lista de histórico e o nível de execuções e reversões pode ser ilimitado simplesmente percorrendo a lista de histórico do fim para o início ou do início para fim. Unidade 2 – Padrões GoF Padrões de Projetos de Software Command • Estrutura: Unidade 2 – Padrões GoF Padrões de Projetos de Software Command – Código • Loja.java: public class Loja { protected String nomeDaLoja; public Loja(String nome) { nomeDaLoja = nome; } public void executarCompra(double valor) { Compra compra = new Compra(nomeDaLoja); compra.setValor(valor); } } Unidade 2 – Padrões GoF Padrões de Projetos de Software Command – Código • Exemplo: • Sistema de Pagamento de Loja Unidade 2 – Padrões GoF Padrões de Projetos de Software Command – Código • Loja.java: public class Compra { private static int CONTADOR_ID; protected int idNotaFiscal; protected String nomeDaLoja; protected double valorTotal; public Compra(String nomeDaLoja) { this.nomeDaLoja = nomeDaLoja; idNotaFiscal = ++CONTADOR_ID; } public void setValor(double valor) { this.valorTotal = valor; } public String getInfoNota() { return new String("Nota fiscal nº: " + idNotaFiscal + "\nLoja: " + nomeDaLoja + "\nValor: " + valorTotal); } } Unidade 2 – Padrões GoF Padrões de Projetos de Software Command – Código – ANTI-PATTERN!!! • Loja.java: public void executarCompra(double valor, FormaDePagamento frmPag){ Compra compra = new Compra(nomeDaLoja); compra.setValor(valor); if(frmPag == FormaDePagamento.CartaoDeCredito){ new PagamentoCartaoCredito().processarCompra(compra); } else if(frmPag == FormaDePagamento.CartaoDeDebito){ new PagamentoCartaoDebito().processarCompra(compra); } else if(frmPag == FormaDePagamento.Boleto){ new PagamentoBoleto().processarCompra(compra); } } Unidade 2 – Padrões GoF Padrões de Projetos de Software Command – Código • Agora, aplicando o padrão! Unidade 2 – Padrões GoF Padrões de Projetos de Software Command • Exemplo: Unidade 2 – Padrões GoF Padrões de Projetos de Software Command – Código • PagamentoCommand.java: public interface PagamentoCommand { void processarCompra(Compra compra); } Unidade 2 – Padrões GoF Padrões de Projetos de Software Command – Código • PagamentoBoleto.java: public class PagamentoBoleto implements PagamentoCommand { @Override public void processarCompra(Compra compra) { System.out.println("Boleto criado!\n" + compra.getInfoNota()); } } Unidade 2 – Padrões GoF Padrões de Projetos de Software Command – Código – Usando o Padrão! • Loja.java: public void executarCompra(double valor, PagamentoCommand frmPag) { Compra compra = new Compra(nomeDaLoja); compra.setValor(valor); frmPag.processarCompra(compra); } Unidade 2 – Padrões GoF Padrões de Projetos de Software Command • Observação: • O padrão tem um conceito muito simples, utilizase apenas da herança para agrupar classes e obrigar que todas tenham uma mesma interface em comum. • A primeira vista o padrão pode ser confundido com o padrão Template Method, pois ambos utilizam a herança para unificar a interface de várias classes. Unidade 2 – Padrões GoF Padrões de Projetos de Software Command • Observação: • A diferença básica é que no padrão Command não existe a ideia de um “algoritmo” que será executado. • No padrão Template Method as subclasses definem apenas algumas operações, sem alterar o esqueleto de execução. • O padrão Command não oferece uma maneira de execução de suas subclasses, apenas garante que todas executem determinada requisição. Unidade 2 – Padrões GoF Padrões de Projetos de Software Interpreter Unidade 2 – Padrões GoF Padrões de Projetos de Software Interpreter • Apresentação: • Padrão de projeto utilizado para modelar a gramática para uma linguagem específica a um domínio de problemas. Unidade 2 – Padrões GoF Padrões de Projetos de Software Interpreter • Aplicabilidade: • Analisadores de expressões regulares, expressões algébricas e partituras musicais (um dado som e sua duração), além de linguagens de consulta (query language) e protocolos de comunicação são exemplos da aplicabilidade deste padrão de projeto. Unidade 2 – Padrões GoF Padrões de Projetos de Software Interpreter • Estrutura: Unidade 2 – Padrões GoF Padrões de Projetos de Software Interpreter • Descrição: • AbstractExpression declara a operação comum a todos os elementos na árvore de sintaxe abstrata, enquanto TerminalExpression implementa tal operação para um determinado elemento terminal (que não pode ser definido em termos de outros elementos). • NonterminalExpression implementa a mesma operação de forma que esta possa ser chamada recursivamente para cada símbolo na gramática e Context possui a informação que é global ao interpretador. Unidade 2 – Padrões GoF Padrões de Projetos de Software Interpreter • Descrição: • Como exemplo, tem-se, a seguir, a gramática que define expressões regulares: Unidade 2 – Padrões GoF Padrões de Projetos de Software Interpreter • Exemplo: • Sistema de Conversão de Algarismos Romanos Unidade 2 – Padrões GoF Padrões de Projetos de Software Interpreter • Exemplo: Unidade 2 – Padrões GoF Padrões de Projetos de Software Interpreter – Código • Contexto.java: public class Contexto { protected String input; protected int output; public Contexto(String input) { this.input = input; } public String getInput() { return input; } public void setInput(String input) { this.input = input; } public int getOutput() { return output; } public void setOutput(int output) { this.output = output; } } Unidade 2 – Padrões GoF Padrões de Projetos de Software Interpreter – Código • NumeroRomanoInterpreter.java: public abstract class NumeroRomanoInterpreter { public void interpretar(Contexto contexto) { if (contexto.getInput().length() == 0) { return; } // Os valores nove e quatro são os únicos que possuem duas casas // Ex: IV, IX if (contexto.getInput().startsWith(nove())) { adicionarValorOutput(contexto, 9); consumirDuasCasasDoInput(contexto); } else if (contexto.getInput().startsWith(quatro())) { adicionarValorOutput(contexto, 4); consumirDuasCasasDoInput(contexto); } else if (contexto.getInput().startsWith(cinco())) { adicionarValorOutput(contexto, 5); consumirUmaCasaInput(contexto); } // Os valores de um são os únicos que repetem, ex: III, CCC, MMM while (contexto.getInput().startsWith(um())) { adicionarValorOutput(contexto, 1); consumirUmaCasaInput(contexto); } } private void consumirUmaCasaInput(Contexto contexto) { contexto.setInput(contexto.getInput().substring(1)); } private void consumirDuasCasasDoInput(Contexto contexto) { contexto.setInput(contexto.getInput().substring(2)); } } Unidade 2 – Padrões GoF Padrões de Projetos de Software Interpreter – Código • NumeroRomanoInterpreter.java: public abstract class NumeroRomanoInterpreter { ... public abstract String um(); public abstract String quatro(); public abstract String cinco(); public abstract String nove(); public abstract int multiplicador(); } Unidade 2 – Padrões GoF Padrões de Projetos de Software Interpreter – Código • UmDigitoRomano.java: public class UmDigitoRomano extends NumeroRomanoInterpreter { @Override public String um() { return "I"; } @Override public String quatro() { return "IV"; } @Override public String cinco() { return "V"; } @Override public String nove() { return "IX"; } @Override public int multiplicador() { return 1; } Unidade 2 – Padrões GoF Padrões de Projetos de Software Interpreter – Código • DoisDigitoRomano.java: public class DoisDigitosRomano extends NumeroRomanoInterpreter { @Override public String um() { return "X"; } @Override public String quatro() { return "XL"; } @Override public String cinco() { return "L"; } @Override public String nove() { return "XC"; } @Override public int multiplicador() { return 10; } Unidade 2 – Padrões GoF Padrões de Projetos de Software Interpreter – Código • Cliente.java: public static void main(String[] args) { ArrayList interpretadores = new ArrayList(); interpretadores.add(new QuatroDigitosRomano()); interpretadores.add(new TresDigitosRomano()); interpretadores.add(new DoisDigitosRomano()); interpretadores.add(new UmDigitoRomano()); String numRomano = "CXCIV"; Contexto contexto = new Contexto(numeroRomano); for (NumeroRomanoInterpreter numRomInterpreter : interpretadores) { numRomInterpreter.interpretar(contexto); } System.out.println(numRomano+"="+Integer.toString(contexto.getOutput())); } Unidade 2 – Padrões GoF Padrões de Projetos de Software Iterator Unidade 2 – Padrões GoF Padrões de Projetos de Software Iterator • Apresentação: • Este padrão de projeto fornece uma interface comum para que uma coleção de objetos possa ser percorrida sem, no entanto, que a aplicação tome conhecimento de como tais objetos estão agrupados. Unidade 2 – Padrões GoF Padrões de Projetos de Software Iterator • Aplicabilidade: • A utilização deste padrão de projeto possibilita à aplicação ter acesso ao conteúdo de um objeto agregado sem que sua representação interna seja exposta. • A coleção de objetos pode ser percorrida em ambas as direções, de acordo com a declaração da interface. Unidade 2 – Padrões GoF Padrões de Projetos de Software Iterator • Estrutura: Unidade 2 – Padrões GoF Padrões de Projetos de Software Iterator • Descrição: • Collection é a interface comum que disponibiliza a assinatura do método createIterator(), entre outros, que deve ser implementado pelas classes descendentes e cujas implementações permitem o percorrimento da coleção de objetos (agregado). • Assim, cada coleção concreta implementa o algoritmo de percorrimento de acordo com a representação de seus dados, retornando à aplicação uma referência à interface Iterator, que apresenta uma interface comum utilizada para percorrer da coleção de objetos. Unidade 2 – Padrões GoF Padrões de Projetos de Software Iterator • Exemplo: • Exibir lista de canais de tv por assinatura Unidade 2 – Padrões GoF Padrões de Projetos de Software Iterator – Código • Representação Simples: ArrayList<Canal> arrayListDeCanais = new ArrayList<Canal>(); Canal[] matrizDeCanais = new Canal[5]; for (Canal canal : arrayListDeCanais) { System.out.println(canal.nome); } for (int i = 0; i < matrizDeCanais.length; i++) { System.out.println(matrizDeCanais[i].nome); } Unidade 2 – Padrões GoF Padrões de Projetos de Software Iterator – Código • Usando o Padrão: Unidade 2 – Padrões GoF Padrões de Projetos de Software Iterator – Código • AgregadoDeCanais.java: public interface AgregadoDeCanais { IteradorInterface criarIterator(); } Unidade 2 – Padrões GoF Padrões de Projetos de Software Iterator – Código • CanaisEsportes.java: public class CanaisEsportes implements AgregadoDeCanais { protected ArrayList<Canal> canais; public CanaisEsportes() { canais = new ArrayList<Canal>(); canais.add(new Canal("Esporte ao vivo")); canais.add(new Canal("Basquete 2011")); canais.add(new Canal("Campeonato Italiano")); canais.add(new Canal("Campeonato Espanhol")); canais.add(new Canal("Campeonato Brasileiro")); } @Override public IteradorListaDeCanais criarIterator() { return new IteradorListaDeCanais(canais); } } Unidade 2 – Padrões GoF Padrões de Projetos de Software Iterator – Código • Classe que utilizar Matriz: @Override public IteradorInterface criarIterator() { return new IteradorMatrizDeCanais(canais); } Unidade 2 – Padrões GoF Padrões de Projetos de Software Iterator – Código • IteradorInterface.java: public interface IteradorInterface { void first(); void next(); boolean isDone(); Canal currentItem(); } Unidade 2 – Padrões GoF Padrões de Projetos de Software Iterator – Código • IteradorListaDeCanais.java: public class IteradorListaDeCanais implements IteradorInterface { protected ArrayList<Canal> lista; protected int contador; protected IteradorListaDeCanais(ArrayList<Canal> lista) { this.lista = lista; contador = 0; } public void first() { contador = 0; } public void next() { contador++; } public boolean isDone() { return contador == lista.size(); } public Canal currentItem() { if (isDone()) { contador = lista.size() - 1; } else if (contador < 0) { contador = 0; } return lista.get(contador); } } Unidade 2 – Padrões GoF Padrões de Projetos de Software Iterator – Código • IteradorListaDeCanais.java: public class IteradorMatrizDeCanais implements IteradorInterface { protected Canal[] lista; protected int contador; public IteradorMatrizDeCanais(Canal[] lista) { this.lista = lista; } @Override public void first() { contador = 0; } @Override public void next() { contador++; } @Override public boolean isDone() { return contador == lista.length; } @Override public Canal currentItem() { if (isDone()) { contador = lista.length - 1; } else if (contador < 0) { contador = 0; } return lista[contador]; } } Unidade 2 – Padrões GoF Padrões de Projetos de Software Iterator – Código • Cliente.java: public static void main(String[] args) { AgregadoDeCanais canaisDeEsportes = new CanaisEsportes(); System.out.println("Canais de Esporte:"); for (IteradorInterface it = canaisDeEsportes.criarIterator(); !it.isDone(); it.next()){ System.out.println(it.currentItem().nome); } AgregadoDeCanais canaisDeFilmes = new CanaisFilmes(); System.out.println("\nCanais de Filmes:"); for (IteradorInterface it = canaisDeFilmes.criarIterator(); !it.isDone(); it.next()) { System.out.println(it.currentItem().nome); } } Unidade 2 – Padrões GoF Padrões de Projetos de Software Mediator Unidade 2 – Padrões GoF Padrões de Projetos de Software Mediator • Apresentação: • Este padrão de projeto provê uma interface unificada a um conjunto de interfaces em um subsistema, fazendo com que a comunicação entre os vários objetos do subsistema seja realizada por um objeto. Desta forma, os objetos do subsistema deixam de manter relações entre si, reduzindo, assim, o acoplamento. Unidade 2 – Padrões GoF Padrões de Projetos de Software Mediator • Aplicabilidade: • A aplicabilidade para este padrão de projeto dá-se quando se quer separar a comunicação que vários objetos têm entre si através de uma interface bem definida, diminuindo, assim, suas interdependências. Unidade 2 – Padrões GoF Padrões de Projetos de Software Mediator • Estrutura: Unidade 2 – Padrões GoF Padrões de Projetos de Software Mediator • Descrição: • Objetos Colleague são desacoplados uns dos outros. • As classes concretas de Colleague “conversam” com a implementação concreta de Mediator, que, por sua vez, conduz a troca de mensagens entre objetos Colleague. Unidade 2 – Padrões GoF Padrões de Projetos de Software Mediator • Exemplo: • Sistema de troca de mensagens entre celulares de diferentes SOs Unidade 2 – Padrões GoF Padrões de Projetos de Software Memento Unidade 2 – Padrões GoF Padrões de Projetos de Software Memento • Apresentação: • Este padrão de projeto baseia-se em dois objetos: o objeto Originator e o objeto Caretaker. • O primeiro é qualquer objeto da aplicação, enquanto o segundo necessita realizar algum processamento no primeiro, mas precisa que o estado inicial possa ser restaurado. • Desta forma, o conceito de encapsulamento não é violado, o que, de outra forma, exporia à aplicação os detalhes de implementação do objeto que sofrerá o processamento. Unidade 2 – Padrões GoF Padrões de Projetos de Software Memento • Aplicabilidade: • Quando se deseja realizar algum processamento temporário em determinado objeto da aplicação, o padrão de projeto Memento é aplicado de tal forma que um “instantâneo” (snapshot) do estado (ou de parte deste) do objeto em questão seja salvo para ser restaurado posteriormente ao processamento realizado. Unidade 2 – Padrões GoF Padrões de Projetos de Software Memento • Estrutura: Unidade 2 – Padrões GoF Padrões de Projetos de Software Memento • Descrição: • O objeto Caretaker deve realizar algum processamento com o objeto Originator, possivelmente mudando seu estado. • Antes que isto aconteça, o objeto Caretaker pede ao objeto Originator por uma referência a Memento, realiza o processamento desejado e devolve a referência Memento ao objeto Originator para que seu estado seja restaurado. Unidade 2 – Padrões GoF Padrões de Projetos de Software Memento • Exemplo: • Editor de texto, com recurso de recuperação de estados anteriores ao atual. Unidade 2 – Padrões GoF Padrões de Projetos de Software Observer Unidade 2 – Padrões GoF Padrões de Projetos de Software Observer • Apresentação: • O objetivo deste padrão de projeto é definir uma relação de dependência de um para muitos entre um conjunto de objetos. • Desta forma, quando um objeto muda de estado todos seus dependentes são notificados de tal mudança. Unidade 2 – Padrões GoF Padrões de Projetos de Software Observer • Apresentação: • De outra forma, se pode dizer que um ou mais objetos, denominados observadores (observers) ou ouvintes (listeners) são registrados (ou se registram) para observervar um determinado evento que pode acontecer por meio de um objeto observado (subject). • Normalmente, este objeto observado mantém uma coleção de observadores. Unidade 2 – Padrões GoF Padrões de Projetos de Software Observer • Aplicabilidade: • Este padrão de projeto é utilizado quando se deseja observar um evento externo, tal como, uma ação do usuário, o que é muito empregado em programação orientada a eventos. • Mudanças no valor de propriedades (variáveis) também empregam o uso deste padrão de projeto. Unidade 2 – Padrões GoF Padrões de Projetos de Software Observer • Aplicabilidade: • A arquitetura Modelo-Visão-Controlador (MVC – ModelView-Controller) faz uso freqüente deste padrão, pois ele é empregado de forma a criar um baixo acoplamento entre o Modelo e a Visão fazendo com que uma mudança no Modelo alerte os seus observadores, que são, neste caso, as visões. Unidade 2 – Padrões GoF Padrões de Projetos de Software Observer • Estrutura: Unidade 2 – Padrões GoF Padrões de Projetos de Software Observer • Descrição: • A classe Subject é utilizada por classes concretas como interface comum para que objetos possam se registrar como observadores, bem como para que possam ser removidos, sendo que cada classe concreta pode ter uma coleção de observadores. • Qualquer classe pode ser um observador desde que implemente a interface Observer e se registre com uma classe concreta de Subject. Assim, os observadores serão notificados sempre que o estado da classe concreta de Subject que os tenha registrado mude. Unidade 2 – Padrões GoF Padrões de Projetos de Software Observer • Exemplo: • Representação de dados, em diversos formatos (Tabela, Porcentagem, Gráfico Barras, Etc.) Unidade 2 – Padrões GoF Padrões de Projetos de Software State Unidade 2 – Padrões GoF Padrões de Projetos de Software State • Apresentação: • Este padrão de projeto permite que um objeto modifique seu comportamento de acordo com a mudança de seu estado interno. • Assim, tem-se a impressão que o objeto muda sua classe. Unidade 2 – Padrões GoF Padrões de Projetos de Software State • Aplicabilidade: • O uso deste padrão de projeto dá-se quando o comportamento de um objeto depende de seu estado e este comportamento deve se modificar em tempo de execução (runtime) de acordo com este estado e, também, quando muitas declarações condicionais (ifelse-if-else) dependem do estado do objeto. Unidade 2 – Padrões GoF Padrões de Projetos de Software State • Aplicabilidade (Cont). : • Neste caso, cada operação, que é realizada de acordo com um valor constante, deve ser transferida para uma classe própria. • Esta transferência permite tratar o estado do objeto como um objeto por si só. Unidade 2 – Padrões GoF Padrões de Projetos de Software State • Estrutura: Unidade 2 – Padrões GoF Padrões de Projetos de Software State • Descrição: • Context pode ser qualquer classe na aplicação que contém vários estados internos. • Quando o método request() é invocado sobre o objeto contexto, o processamento é delegado ao objeto estado (State). Unidade 2 – Padrões GoF Padrões de Projetos de Software State • Descrição (Cont.): • Assim, os estados concretos (ConcreteStateA, ConcreteStateB) tratam (manipulam) as requisições provenientes do contexto e os estados concretos têm suas próprias implementações para o tratamento da requisição. • Desta forma, quando Context muda seu estado (o(s) valor(es) de seu(s) atributo(s) é(são) alterado(s)), seu comportamento também muda. Unidade 2 – Padrões GoF Padrões de Projetos de Software State • Exemplo: • Gerenciar os vários estados de um personagens de game. (Ex: Mario) Unidade 2 – Padrões GoF Padrões de Projetos de Software Strategy Unidade 2 – Padrões GoF Padrões de Projetos de Software Strategy • Apresentação : • Este padrão de projeto define uma família de algoritmos, os encapsula e os torna intercambiáveis. • Estes algoritmos podem variar independente da aplicação cliente que os usa. Unidade 2 – Padrões GoF Padrões de Projetos de Software Strategy • Aplicabilidade: • Este padrão de projeto provê uma forma de configurar uma classe com um de vários comportamentos ou algoritmos. • Além disto, é possível esconder da aplicação as estruturas de dados, possivelmente complexas, utilizadas pelos diversos algoritmos. Unidade 2 – Padrões GoF Padrões de Projetos de Software Strategy • Aplicabilidade (Cont.): • Isto permite que diferentes regras de negócios possam ser utilizadas dependendo do contexto no qual elas ocorram, significando que este padrão de projeto fornece um meio de configurar uma classe com um entre vários comportamentos. Unidade 2 – Padrões GoF Padrões de Projetos de Software Strategy • Estrutura: Unidade 2 – Padrões GoF Padrões de Projetos de Software Strategy • Descrição: • Encapsula algoritmos em classes, permitindo que eles possam variar independente da aplicação cliente que os usa. Isto possibilita a aplicação do princípio denominado Princípio Aberto-Fechado (Open-Closed Principle), no qual uma classe está aberta para extensões enquanto mantém-se fechado para alterações. Unidade 2 – Padrões GoF Padrões de Projetos de Software Strategy • Descrição (Cont.): • Tal princípio é alcançado pelo uso deste padrão de projeto, pois a aplicação cliente faz uso de uma classe base (classe abstrata ou interface) e os detalhes de implementação estão presentes em classes derivadas. • A aplicação cliente não sofre impacto no caso do aumento de classes derivadas, nem tampouco com eventuais mudanças que essas classes venham a sofrer. Unidade 2 – Padrões GoF Padrões de Projetos de Software Strategy • Descrição (Cont.): • Com isto, a aplicação cliente minimiza o acoplamento, pois mantém um vínculo com a abstração (classe abstrata ou interface) e não com uma implementação específica. Unidade 2 – Padrões GoF Padrões de Projetos de Software Strategy • Exemplo: • Cálculo de impostos de acordo com o cargo do funcionário. Unidade 2 – Padrões GoF Padrões de Projetos de Software Template Method Unidade 2 – Padrões GoF Padrões de Projetos de Software Template Method • Apresentação: • Padrão de projeto cuja função é generalizar um processo, em um nível mais genérico, em um conjunto de passos, permitindo que etapas comuns sejam implementadas e que etapas específicas tenham suas implementações realizadas por classes descendentes. • Em outras palavras, este padrão permite que subclasses de uma classe comum possam variar partes de um algoritmo mais geral. Unidade 2 – Padrões GoF Padrões de Projetos de Software Template Method • Aplicabilidade: • Partes de um algoritmo genérico são implementadas em uma classe comum a partir da qual suas subclasses podem ou devem implementar as partes específicas. Unidade 2 – Padrões GoF Padrões de Projetos de Software Template Method • Estrutura: Unidade 2 – Padrões GoF Padrões de Projetos de Software Template Method • Descrição: • A classe AbstractClass possui o método templateMethod() e as assinaturas de métodos abstratos, usados pelo método template, que devem ser implementados por classes descendentes. • Uma vez que a classe contendo o método com os passos comuns (ou genéricos) tenha sido criada, várias classes concretas podem existir, cada uma implementando as partes específicas do algoritmo. Unidade 2 – Padrões GoF Padrões de Projetos de Software Template Method • Descrição (Cont.): • Algumas vezes um algoritmo genérico pode-se valer de passos que, se não implementados por classes descendentes, podem não existir ou são padronizados. • Neste caso, as classes descendentes podem escolher ou não realizar suas implementações. Unidade 2 – Padrões GoF Padrões de Projetos de Software Template Method • Descrição (Cont.): • Outras vezes, dependendo do projeto, AbstractClass pode ser, na verdade, uma classe concreta, cujos passos específicos de um algoritmo podem ou devem ser implementadas por classes descendentes. Unidade 2 – Padrões GoF Padrões de Projetos de Software Template Method • Exemplo: • Ordenação de uma Playlist de MP3 Unidade 2 – Padrões GoF Padrões de Projetos de Software Visitor Unidade 2 – Padrões GoF Padrões de Projetos de Software Visitor • Apresentação: • Representa uma operação que é executada em uma estrutura de objetos. • Novas operações são definidas sem, no entanto, conhecer as classes dos objetos sobre as quais elas serão executadas. Unidade 2 – Padrões GoF Padrões de Projetos de Software Visitor • Aplicabilidade: • Este padrão de projeto pode ser utilizado quando uma estrutura de objetos contém muitas classes com interfaces diferentes e se deseja executar operações distintas ou sem relação entre si. Unidade 2 – Padrões GoF Padrões de Projetos de Software Visitor • Aplicabilidade (Cont.): • Isto evita a “poluição” de código e mantém códigos relacionados em uma única classe. • Além disto, normalmente a frequência de mudanças nas estruturas de objetos é pequena, enquanto que novas operações podem ser acrescentadas à medida que os requisitos se modificam. Unidade 2 – Padrões GoF Padrões de Projetos de Software Visitor • Estrutura: Unidade 2 – Padrões GoF Padrões de Projetos de Software Visitor • Descrição: • Este padrão de projeto é aplicado quando há necessidade de se executar operações semelhantes em objetos de diferentes tipos agrupados em uma estrutura, possivelmente uma coleção. • Ele também fornece um meio prático para o acréscimo de novos visitors que estendem funcionalidades préexistentes sem que o código seja modificado. Unidade 2 – Padrões GoF Padrões de Projetos de Software Visitor • Exemplo: • Representação de Árvore Binária Unidade 2 – Padrões GoF