Módulo III Padrões GOF-II: Iterator e Composite Professores Eduardo Bezerra – [email protected] Ismael H F Santos – [email protected] April 05 Prof. Ismael H. F. Santos - [email protected] 1 Ementa Padrões – Parte II Julho 06 Iterator Composite Bridge Prof(s). Eduardo Bezerra & Ismael H. F. Santos 2 Bibliografia Craig Larman, Utilizando UML e Padrões, Ed Bookman Eric Gamma, et ali, Padrões de Projeto, Ed Bookman Martin Fowler, Analysis Patterns - Reusable Object Models, Addison-Wesley,1997 Martin Fowler, Refatoração - Aperfeiçoando o projeto de código existente, Ed Bookman Julho 06 Prof(s). Eduardo Bezerra & Ismael H. F. Santos 3 Livros Core Java 2, Cay S. Horstmann, Gary Cornell Volume 1 (Fundamentos) Volume 2 (Características Avançadas) Java: Como Programar, Deitel & Deitel Thinking in Patterns with JAVA, Bruce Eckel Gratuito. http://www.mindview.net/Books/TIJ/ Julho 06 Prof(s). Eduardo Bezerra & Ismael H. F. Santos 4 POO-Java Julho 06 Padrões Parte II Prof(s). Eduardo Bezerra & Ismael H. F. Santos 5 POO-Java Julho 06 Iterator Prof(s). Eduardo Bezerra & Ismael H. F. Santos 6 Iterator Toda coleção possui uma representação interna para o armazenamento e organização de seus elementos. Por outro lado, essa coleção deve permitir que seus elementos sejam acessados sem que sua estrutura interna seja exposta. De uma maneira geral, pode-se desejar que estes elementos sejam percorridos de várias maneira, sem no entanto ter que modificar a interface da coleção em função do tipo de varredura desejado. de frente para trás, vice-versa, ou mesmo em ordem aleatória. Julho 06 Prof(s). Eduardo Bezerra & Ismael H. F. Santos 7 Iterator O padrão Iterator permite descrever uma forma de percorrer os elementos de uma coleção sem violar o encapsulamento dessa coleção. Intenção: iterar sobre (percorrer seqüencialmente) uma coleção de objetos sem expor sua representação. Obedecer o princípio do encapsulamento Julho 06 Prof(s). Eduardo Bezerra & Ismael H. F. Santos 8 Iterator Solução: um objeto intermediário (iterator) é usado entre o cliente e a coleção de objetos. Este objeto conhece a estrutura interna da coleção a ser percorrida, e apresenta uma interface para percorrer tal estrutura. Esta interface é independente dessa estrutura interna. Os clientes que desejam percorrer a coleção utilizam a interface do objeto intermediário, em vez de se comunicarem diretamente com a coleção de objetos. Julho 06 Prof(s). Eduardo Bezerra & Ismael H. F. Santos 9 Iterator Requisitos de um iterador Um modo de localizar um elemento específico da coleção, tal como o primeiro elemento. Um modo de obter acesso ao elemento atual. Um modo de obter o próximo elemento. Um modo de indicar que não há mais elementos a percorrer. Exemplo em Java As classes List, Set e Sorted são subclasses de Collection, e herdam um método iterator() que retorna um objeto iterador. O objeto Iterator possui métodos hasNext() e next(). Julho 06 Prof(s). Eduardo Bezerra & Ismael H. F. Santos 10 Iterator (exemplo) // ICollection.java // interface para obtenção de Iterator para coleções public interface ICollection { // obtenção de um Iterator public IIterator getIterator(); // determina existência de um elemento public boolean has(Object object); // adição de um elemento public boolean add(Object object); // remoção de um elemento public boolean remove(Object object); // remoção de todos os elementos public void removeAll(); } Julho 06 Prof(s). Eduardo Bezerra & Ismael H. F. Santos 11 Iterator (exemplo) // IIterator.java public interface IIterator { // verifica a existência de um próximo elemento public boolean hasNext(); // retorna o próximo elemento public Object next(); } Julho 06 Prof(s). Eduardo Bezerra & Ismael H. F. Santos 12 Iterator (estrutura) Julho 06 Prof(s). Eduardo Bezerra & Ismael H. F. Santos 13 Iterator (participantes) Iterator Define um interface para o acesso e varredura; ConcreteIterator Implementa a interface do Iterator; Mantém referência (cursor) ao objeto que está sendo percorrido, podendo calcular qual o elemento seguinte. Aggregate Define um interface para a criação do objeto Iterator; ConcreteAggregate Implementa o método da interface que retorna uma instância do ConcreteIterator. Julho 06 Prof(s). Eduardo Bezerra & Ismael H. F. Santos 14 Iterator (aplicabilidade) O uso do padrão Iterator se aplica quando se quer: acessar o conteúdo de objeto agregados sem expor sua representação interna; dar suporte a mais de uma maneira de percorrer a lista; prover interface única para percorrer estruturas agregadas diferentes. Julho 06 Prof(s). Eduardo Bezerra & Ismael H. F. Santos 15 Iterator (conseqüências) Mantém separadas a representação interna e a responsabilidade de navegação pelas partes. O iterador conhece a estrutura interna das partes, mas os clientes do iterador não conhecem. Move da coleção de objetos para o objeto iterator a responsabilidade de acesso e varredura da coleção. A coleção ainda é responsável por criar seus próprios iteradores e o faz através do padrão “Factory Method”. Há a possibilidade de utilizar mais de um iterador simultaneamente. Dá suporte a múltiplas maneiras de percorrer a coleção e, se necessário, essas varreduras podem ocorrer ao mesmo tempo. Julho 06 Prof(s). Eduardo Bezerra & Ismael H. F. Santos 16 POO-Java Julho 06 Composite Prof(s). Eduardo Bezerra & Ismael H. F. Santos 17 Composite São comuns as situações onde temos que lidar com uma coleção de elementos estruturada hierarquicamente (em vez coleções “lineares”). Problema: como criar objetos utilizando partes de tal forma que tanto o objeto todo quanto os objetos parte forneçam a mesma interface para os seus clientes? Composições podem cumprir com este requisito e ainda permitir: o tratamento da composição como um todo; ignorar as diferenças entre composições e elementos individuais; a adição transparente de novos tipos a hierarquia; a simplificação do cliente. Julho 06 Prof(s). Eduardo Bezerra & Ismael H. F. Santos 18 Composite (estrutura) Julho 06 Prof(s). Eduardo Bezerra & Ismael H. F. Santos 19 Composite (exemplo) Expressões lógicas (booleanas) Julho 06 Prof(s). Eduardo Bezerra & Ismael H. F. Santos 20 Composite (conseqüências) Objetos complexos podem ser compostos de objetos mais simples recursivamente. Permite forma assim uma hierarquia de objetos O cliente pode tratar objetos “parte” e objetos “todo” da mesma forma. Isso resulta na simplificação deste cliente. Os clientes normalmente não sabem (e nem devem se preocupar) se eles estão tratando um componente individual ou composto. Facilita a adição de novos componentes: o cliente não tem que mudar com a adição de novos objetos Julho 06 Sejam eles simples ou compostos Prof(s). Eduardo Bezerra & Ismael H. F. Santos 21 Composite (conseqüências) O projeto pode ficar geral demais, o que torna mais difícil restringir os possíveis componentes de um objeto composto. Julho 06 Por exemplo, em uma hierarquia que contenha documentos e suas partes (seções, parágrafos, etc.), podemos compor seções com documentos, etc. o que não faz sentido Prof(s). Eduardo Bezerra & Ismael H. F. Santos 22 Composite (aplicabilidade) Quando é necessário representar hierarquias do tipo todo-parte. Quando é necessário tratar todo e respectivas partes de forma indistinta. Julho 06 Prof(s). Eduardo Bezerra & Ismael H. F. Santos 23 POO-Java Julho 06 Bridge Prof(s). Eduardo Bezerra & Ismael H. F. Santos 24 Bridge Intenção: desacoplar uma abstração de sua implementação de tal forma que a implementação possa ser facilmente trocada. Solução: encapsular os detalhes de implementação em um objeto que é um componente da abstração Julho 06 Prof(s). Eduardo Bezerra & Ismael H. F. Santos 25 Bridge Considere a construção de um módulo para desenhar figuras. Considere que há duas classes externas de desenho a serem utilizadas: DP1 e DP2 Primeira versão: “somente retângulos devem ser desenhados”. Solução: Julho 06 Prof(s). Eduardo Bezerra & Ismael H. F. Santos 26 Bridge Suponha agora, o seguintes novos requisitos: “As classes externas agora desenham círculos. Portanto, nosso módulo de desenho deve também ter a possibilidade de desenhar círculos”. “Além disso, o cliente do nosso módulo de desenho não precisa saber a diferença entre um retângulo e um círculo.” Solução: Criamos uma classe abstrata Shape, e fazemos com que ela seja superclasse tanto de Rectangle quanto de Circle. O cliente agora se comunica com objetos Shape. Sendo assim, temos uma nova solução, apresentada a seguir... Julho 06 Prof(s). Eduardo Bezerra & Ismael H. F. Santos 27 Bridge Julho 06 Prof(s). Eduardo Bezerra & Ismael H. F. Santos 28 Bridge Infelizmente, a solução da figura anterior introduz alguns problemas: O que acontece se preciso dar suporte a um novo programa de desenho? E se um novo tipo de Figura (Shape) tiver que ser adicionado? O que aconteceria com a complexidade de manutenção neste módulo quando a quantidade de tipos de figura e de módulos externos de desenho chegasse à cada das dezenas? Resposta: explosão de classes. Julho 06 Prof(s). Eduardo Bezerra & Ismael H. F. Santos 29 Bridge A explosão de classes surge porque, nesta solução, a abstração (ou seja, os tipos de Shape) e a implementação (os programas de desenho) estão fortemente acoplados. i.e., cada tipo de figura (abstração) deve saber que tipo de módulo externo (implementação) ele deve utilizar. Precisamos de um modo de separar (desacoplar) as variações na abstração das variações na implementação, de tal forma que o número de classes cresça somente linearmente. Esta é exatamente a intenção (objetivo) do padrão Bridge. Julho 06 Prof(s). Eduardo Bezerra & Ismael H. F. Santos 30 Bridge Julho 06 Prof(s). Eduardo Bezerra & Ismael H. F. Santos 31 Bridge (estrutura) Julho 06 Prof(s). Eduardo Bezerra & Ismael H. F. Santos 32 Bridge (exemplo) Java Swing possui diversos “look and feels”. Objetos JFrame, JButton, etc. possuem um componente interno (peer) que é construído para com um look and feel particular. No entanto, clientes (programadores) somente precisam interagir com JFrame, JButton, etc. Julho 06 Prof(s). Eduardo Bezerra & Ismael H. F. Santos 33 Bridge (exemplo) O método UIManager.setLookAndFeel define a fábrica concreta para “produtos” do Windows. WindowsLookAndFeel Julho 06 DefaultLookAndFeel Prof(s). Eduardo Bezerra & Ismael H. F. Santos 34 Bridge (exemplo) Exemplo: usando o padrão Bridge para abstrair o driver específico de banco de dados. JDBC imp MySQL JDBC Driver Julho 06 JDBC Implementation Oracle JDBC Driver Prof(s). Eduardo Bezerra & Ismael H. F. Santos Postgress JDBC Driver 35 Bridge (aplicabilidade) Aplicabilidade O padrão Bridge é útil quando se tem uma abstração que tem diferentes implementações. Este padrão permite que a abstração e a sua implementação variem independentemente. Julho 06 Prof(s). Eduardo Bezerra & Ismael H. F. Santos 36