• Nenhum resultado encontrado

Padrões de Projeto. Marco Túlio de Oliveira Valente

N/A
N/A
Protected

Academic year: 2021

Share "Padrões de Projeto. Marco Túlio de Oliveira Valente"

Copied!
53
0
0

Texto

(1)

Padrões de Projeto

(2)

Padrões de Projeto

 Idéia proposta pelo arquiteto Cristopher Alexander:

 A Pattern Language: Towns, Buildings, Construction, 1977

 "Each pattern describes a problem which occurs over and over

again in our environment, and then describes the core of the solution to that problem, in such a way that you can use this

solution a million times over, without ever doing it the same way twice".

 Na área de desenvolvimento de software, popularizados pelo livro:

 Design Patterns: Elements of Reusable Object-Oriented

Software, by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides, Addison-Wesley, 1995

 Conhecido como “GoF (Gang of Four) book”

 Também chamados padrões de desenho

(3)

Padrões de Projeto

 Definição segundo GoF: "descriptions of communicating objects and

classes that are customized to solve a general design problem in a particular context."

 Objetivo de padrões na comunidade de projetistas de sistemas:

 Criar um “catálogo de soluções” que possam ser reutilizadas em

problemas que são recorrentes no desenvolvimento de sistemas

 Criar um “vocabulário comum” para comunicar experiências,

problemas e soluções recorrentes no projeto de sistemas

 Ajudar na documentação e facilitar o entendimento de projetos

 Um padrão somente deve merecer este nome depois que sua

utilidade for comprovada em um certo número de sistemas

(4)

Padrões de Projeto

 Segundo o seu propósito, padrões podem ser:

 Criacionais: tratam do processo de criação de objetos  Estruturais: tratam da composição de classes e objetos  Comportamentais: tratam das interações e distribuição de

responsabilidades entre classes e objetos

 Segundo seu escopo, padrões podem se aplicar a:

 Classes: propõem relacionamentos entre classes e subclasses  Objetos: propõem relacionamentos entre objetos

 Elementos essenciais para se descrever um padrão:

 Nome

 Problema: quando e em que contexto deve-se aplicar o padrão

 Solução: elementos que compõem o padrão

(5)

Padrões de Projeto (GoF)

 Criacionais  Abstract factory  Builder  Factory method  Prototype  Singleton  Estruturais  Adapter  Bridge  Composite  Decorator Facade  Flyweight  Comportamentais  Chain of responsibility  Command  Interpreter  Iterator  Mediator  Memento  Observer  State  Strategy  Template method  Visitor

(6)

Padrões de Projeto (GoF)

 Nome e classificação (criacional, estrutural ou comportamental)  Objetivo: o que este padrão faz?

 Outros nomes

 Motivação: cenários de uso do padrão

 Aplicações: em quais outros cenários o padrão pode ser usado  Estrutura: diagrama de classes do padrão (notação OMT)

 Participantes: papel desempenhado pelas classes do padrão

 Colaboração: “mecânica” de funcionamento do padrão

 Conseqüencias: “trade-offs” resultantes do uso do padrão

 Implementação: como implementar o padrão

 Código de exemplo: implementações de exemplo (em C++)

 Usos conhecidos: sistemas que usam o padrão

(7)

Factory Method

 Define uma interface para criação de objetos, deixando para

subclasses a definição da classe concreta a ser instanciada

 Delega a criação de objetos para subclasses

 Usado quando uma classe não pode antecipar o tipo dos objetos

que a mesma precisa criar.

 Suponha um serviço de nomes descrito pela seguinte classe:

class Registry {

HashTable createTable() { return new HashTable(); } bind(...) { ... }

lookup(...) { ... } }

 Problema: trecho de código acima é pouco robusto a mudanças  Amanhã, podemos querer usar uma tabela persistente, um arquivo

(8)

Factory Method: Exemplo 1

interface Table { ....

}

class PersistentTable implements Table { ....

}

abstract class Registry { // reutilizada em diversos registros abstract Table createTable();

bind(...) { ... } lookup(..) { ... } }

class PersistentRegistry extends Registry {

Table createTable() { return new PersistentTable(); } }

(9)

Factory Method: Estrutura

 Creator: Registry

 FactoryMethod: createTable()  ConcreteCreator: MyRegistry  Product: Table

 ConcreteProduct: HashTable, PersistentTable, XMLTable etc

classe abstrata

subclasse

instancia

pseudocódigo

Fonte: http://www.dofactory.com/Patterns/Patterns.aspx (incluindo figuras dos próximos slides)

(10)

Abstract Factory

 Define uma interface para criação de famílias de objetos, sem

requerer a especificação de suas classes concretas

 Suponha um sistema que utiliza TCP/IP para comunicação  Exemplo de trecho de código deste sistema:

void foo() { ...

TCPSocket s= new TCPSocket(); ...

TCPPort p= new TCPPort(); ....

}

 Problema: trecho de código acima é pouco reutilizável/extensível

 Amanhã, podemos querer estender o sistema para trabalhar com

outros tipos de protocolos (UDP, HTTP)

(11)

Abstract Factory: Exemplo

void foo(ProtocolFactory pf) { ... Socket s= pf.createSocket(); ... Port p= pf.createPort(); .... } ....

class TCPFactory implements ProtocolFactory {

public Socket createSocket() { return new TCPSocket(); } public Port createPort() { return new TCPPort(); }

}

...

ProtocolFactory pf= new TCPFactory(); foo(pf);

(12)

Abstract Factory: Estrutura

 AbstractProductA: Socket  ProductA1: TCPSocket  ProductA2: UDPSocket  AbstractProductB: Port  ProductB1: TCPPort  ProductB2: UDPPort  AbstractFactory: ProtocolFactory  ConcreteFactory1: TCPFactory  ConcreteFactory2: UDPFactory  TCPFactory:  CreateSocket()  CreatePort()  UDPFactory:  CreateSocket()  CreatePort()

(13)

Singleton

 Usado para garantir que uma classe possui uma única instância  Exemplo: servidor com uma única instância (de impressora, de

nomes etc)

class MyServer {

private static MyServer instance;

private MyServer() {} // evita que cliente use new MyServer() public static MyServer getInstance() {

if(instance == null)

instance= new MyServer(); return instance;

} }

 Uso:

(14)

Singleton: Zero Instâncias

 Outra alternativa: classe sem nenhuma instância (zeroton?)

 Todos os métodos e atributos estáticos

 Classe é final (evita declaração de subclasses)

 Construtora privada sem argumentos (evita instanciação)

 Exemplo: class java.lang.Math

public final class Math { ...

private Math() {}

public static double sin (double a) { ... } public static double cos (double a) { ... } ...

(15)

Proxy

 Cria um “intermediário” que controla o acesso a um objeto base  Cliente não possui uma referência direta para o objeto base, mas

sim para o proxy

 Proxy é que possui uma referência para o objeto base  Proxy implementa as mesmas interfaces do objeto base

(16)

Proxy

 Funcionamento:

 cliente invoca método do proxy;

 proxy realiza uma “determinada tarefa” e eventualmente repassa

a requisição do cliente para o objeto base

 Exemplos de proxy (e de sua “determinada tarefa”):

 Remote proxy (stub): marshalling e envio dos parâmetros de uma

chamada remota de métodos para um objeto remoto (stub)

 Virtual proxy: alocação de memória por demanda para objetos

que consomem muita memória

 Protection proxy: controla o acesso ao objeto base por parte de

diferentes clientes

 Cache proxy: armazena em um cache resultados de métodos

idempotentes

 Outros usos (requisitos não-funcionais): tolerância a falhas,

(17)

Adapter

 Converte a interface de uma classe para outra interface, esperada

pelos seus clientes

 Permite que classes trabalhem juntas, o que não seria possível antes

devido à incompatibilidade de interfaces

 Suponha que uma classe possua o seguinte método copy:

Copyable[] copy (Copyable[] v);

 A interface Copyable possui o seguinte método:

boolean isCopyable();

 O método copy apenas copia aqueles elementos de v sobre os quais

uma chamada de isCopyable retorna true

 Suponha, no entanto, que desejamos copiar objetos do tipo Document

(e que não dispomos do código desta classe)

 A classe Document não implementa a interface Copyable, mas

(18)

Adapter: Solução

 Solução: classe DocumentAdapter

class DocumentAdapter implements Copyable { private Document document;

public DocumentAdapter (Document document) { this.document= document;

}

public boolean isCopyable() { return document.isValid(); }

}

 Evidentemente, devemos inserir no vetor a ser copiado objetos do

(19)

Adapter: Estrutura

 Analogia com o diagrama de classes do padrão:

 Target: Copyable  Request: isCopyable()  Adapter: DocumentAdapter  Adaptee: Document  SpecificRequest: isValid

(20)

Adapter: Exemplo

 Skeleton é um adaptador: skeleton objeto remoto f1(...) f2(...) fn(...) requisição

(21)

Façade

 Cria uma interface unificada para um conjunto de interfaces de um

subsistema; define uma interface de mais alto nível, a qual torna a utilização do sistema mais fácil

 Suponha o exemplo de um compilador:

Scanner s= new Scanner(“exemplo1.java”); Parser p= new Parser(s);

AST ast= p.parse(); ...

JVMCodeGenerator jvm= new JVMCodeGenerator(ast); jvm.code()

 Requer conhecimento das interfaces de cada um dos subsistemas

de um compilador (Scanner, Parser, AST, CodeGenerator etc)

 Seria muito mais fácil se existisse um método:

void compila(String nomeArq)

que realizasse todas as tarefas acima

(22)

Decorador

 Adicionam dinamicamente novas responsabilidades a um objeto

 Constituem uma alternativa a subclasses quando se precisa

adicionar novas funcionalidades em uma classe

 São transparentes aos clientes do objeto decorado  Suponha a seguinte interface:

interface Channel {

public void send(byte[] m) throws NetworkException; public byte[] recv() throws NetworkException;

}

 Suponha uma classe TCPChannel:

(23)

Decorador

 Suponha um TCPChannel que compacte/descompacte os dados

enviados/recebidos:

class TCPZipChannel extends TCPChannel {

public void send(byte[] m) throws NetworkException { m= “compactação do vetor m”

super.send(m); }

public byte[] recv() throws NetworkException { byte[] m= super.recv();

m= “descompactação do vetor m” return m;

}

 Suponha um TCPChannel com um buffer associado (dados são

escritos em um buffer; quando buffer cheio são enviados) class TCPBufferChannel extends TCPChannel { .... }

(24)

Decorador

 Algumas combinações possíveis:

 TCPZipChannel  TCPChannel

 TCPBufferedChannel  TCPChannel

 TCPBufferedZipChannel  TCPZipChannel  TCPChannel

 TCPLogChannel  TCPChannel

 TCPLogBufferedZipChannel  TCPBufferedZipChannel 

TCPZipChannel  TCPChannel

 UDPZipChannel  UDPChannel

 UDPBufferedChannel  UDPChannel

 UDPBufferedZipChannel  UDPZipChannel  UDPChannel

 UDPLogChannel  UDPChannel

 UDPLogBufferedZipChannel  UDPBufferedZipChannel 

UDPZipChannel  UDPChannel

(25)

Decorador: Exemplo

 Decorador de canais de comunicação:

interface Channel {

public void send(byte[] m) throws NetworkException; public byte[] recv() throws NetworkException;

}

class ChannelDecorator implements Channel { protected Channel channel;

public ChannelDecorator(Channel ch){ this.channel = ch;

}

public void send(byte[] m) throws NetworkException { channel.send(m);

}

public byte[] recv() throws NetworkException { return channel.recv();

(26)

26

Decorador: Exemplo

 Decorador de canais de comunicação:

public class ZipDecorator extends ChannelDecorator{ public ZipDecorator(Channel c) {

super(c); }

public void send(byte[] m) throws NetworkException { m= “compactação do vetor m”

super.channel.send(m); }

public byte[] recv() throws NetworkException { byte m[] = super.channel.recv();

m= “descompactação do vetor m” return m;

} }

 Outros decoradores: LogChannel, BufferedChannel, XORChannel

(27)

Decorador: Exemplo

 Suponha um TCPChannel que compacte/descompacte os dados

enviados/recebidos:

Channel= new ZipChannel (new TCPChannel());

 Suponha um TCPChannel com um buffer associado:

Channel= new BufferChannel (new TCPChannel());

 Suponha um UDPChannel com um buffer associado:

Channel= new BufferChannel (new UDPChannel());

 Suponha um TCPZipChannel com um buffer associado:

(28)

28

Decorador: Estrutura

 Analogia com exemplo dos canais de Arcademis:

 Component: Channel

 ConcreteComponent: TCPChannel, UDPChannel  Decorator: ChannelDecorator

 ConcreteDecoratorA: ZipChannel

(29)

Iterador

 Disponibilizam modos de acesso a objetos compostos sem expor a

representação interna de tais objetos

 Objetos compostos: listas, árvores, tabelas hash etc

 Encapsulam código para percorrer uma estrutura de dados

 Muitas vezes, deseja-se percorrer uma estrutura de dados sem

conhecer seu tipo concreto

 Para isso, basta que o cliente conheça a interface desta estrutura  Assim, pode-se mudar de estrutura de dados (de uma lista para

uma árvore, por exemplo), sem afetar seus clientes

 Iteradores:

 Disponibilizam uma interface comum para percorrer diversas

estruturas de dados

 Permitem que vários caminhamentos sobre uma estrutura

(30)

30

Iterador: Exemplo

void foo(List list) {

Iterator iterator= list.createIterator(list); iterator.first();

while (!iterator.IsDone()) {

Object item = iterator.CurrentItem(); // Code here to process item.

iterator.next(); } ...

}

class LinkedList implements List { ...

Iterator createIterator (LinkedList list) { return new LinkedListIterator(list);

} ... }

...

(31)

Iterador: Estrutura

Analogia com exemplo anterior:

Aggregate: List

ConcreteAggregate: LinkedList ConcreteIterator: LinkedListIterator

(32)

32

Observador

 Define uma dependência do tipo um-para-muitos entre objetos, de

forma que quando um objeto tem seu estado alterado, todos os seus dependentes são notificados

 Usado quando a mudança do estado de um objeto (chamado de

Subject) requer que outros objetos sejam notificados (chamados de Observers)

(33)

33

Observador: Exemplo

public interface Observer {

public void update(Subject s); }

public class Subject {

private List observers= new LinkedList(); public void addObserver(Observer observer) { observers.add(observer);

}

public void removeObserver(Observer observer) { observers.remove(observer);

}

public void notifyObservers() {

Iterator it= observers.iterator(); while (it.hasNext()) {

Observer obs= (Observer) it.next(); obs.update(this);

} }

(34)

Observador: Exemplo

public class Temperature extends Subject { private double value;

public double getValue() { return value;

}

public void setValue(double value) { this.value= value;

notifyObservers(); }

}

public class TermometerCelsius implements Observer { public void update(Subject s) {

double value= ((Temperature) s).getValue(); System.out.println("Celsius: " + value); }

(35)

Observador: Exemplo

public class TermometerFahrenheit implements Observer { public void update(Subject s) {

double value= 1.8 * ((Temperature) s).getValue() + 32; System.out.println("Fahrenheit: " + value);

} }

public class TesteTemperature {

public static void main(String[] args) { Temperature t= new Temperature(10);

t.addObserver(new TermometerCelsius ()); t.addObserver(new TermometerFahrenheit ()); t.setValue(100); } } Saída: Celsius: 100.0

(36)

Observador: Estrutura

 Analogia com exemplo da Temperatura e dos Termômetros:

 Subject e Observer

 ConcreteSubject: Temperature

 ConcreteObserver: TermometerCelsius, TermometerFahrenheit etc

no exemplo, substituída por um parâmetro em update

(37)

Strategy

 Define uma família de algoritmos, encapsula cada um deles e os

torna intercambiáveis. Este padrão permite que algoritmos sejam mudados independentemente de seus clientes.

 Usado quando uma classe é usuária de um certo algoritmo, por

exemplo, um algoritmo de ordenação

 Como existem diversos algoritmos de ordenação, não se quer

codificar todos eles dentro desta classe class MyList {

ArrayList list;

SortStrategy strategy;

void setSortStrategy (SortStrategy strategy) { this.strategy= strategy;

}

sort() {

strategy.sort(list); }

(38)

Strategy: Exemplo

abstract class SortStrategy { // interface comum aos algoritmos abstract void sort (ArrayList list);

}

class QuickSort extends SortStrategy { void sort (ArrayList list) { .... } }

class ShellSort extends SortStrategy { void sort (ArrayList list) { .... } }

(39)

39

Strategy: Estrutura

 Analogia com exemplo anterior:

 Context: MyList

 Strategy: SortStratety

 ConcreteStrategy: QuickSortStratety, ShellSortStratety etc

(40)

Visitor

 Permite agregar novos métodos a uma hierarquia de classes, sem

modificar as classes existentes

Example: Considere a seguinte hierarquia de Modem.

Problema: Como podemos adicionar um método

(41)

Visitor

Adiciona-se um método genérico accept() na interface Modem e

cria-se uma interface separada ModemVisitor para configurar cada Modem para cada sistema operacional

(42)
(43)
(44)
(45)

Frameworks: Hot Spots

 Marcus Eduardo Markiewicz and Carlos J. P. de Lucena. Object

oriented framework development, Crossroads Magazine, vol. 7, n. 4, p. 3-9, 2001.

“The points of flexibility of a framework are called hot spots. Hot

spots are abstract classes or methods that must be implemented.”

 “Frameworks are not executable. To generate an executable, one

must instantiate the framework by implementing application specific code for each hot spot”.

 “Some features of the framework are not mutable and cannot be

easily altered. These points of immutability constitute the kernel of a framework, also called the frozen spots of the framework.”

 “Frozen spots, unlike hot spots, are pieces of code already

implemented within the framework that call one or more hot spots provided by the implementer. The kernel will be the constant and always present part of each instance of the framework”.

(46)

Componentes, Frameworks, Padrões

 Ralph E. Johnson. Components, frameworks, patterns. SIGSOFT

Soft. Engineering Notes, p.10-17, vol. 22, n. 3, 1997. Componentes: reuso de código

 “The ideal reuse technology provides components that can be easily

connected to make a new system. The software developer does not have to know how the component is implemented, and it is easy for the developer to learn how to use it.”

 “The electric power system is like that; you can buy a toaster from

one store and a television from another, and they will both work at either your home or office. Most people do not know Ohm's Law, yet they have no trouble connecting a new toaster to the power system. Unfortunately, software is not nearly as composable as the electric power system.”

 Componentes da biblioteca java.util: ArrayList, Vector, Stack,

(47)

Frameworks

 Frameworks (ou arcabouços) permitem reuso de projeto  Definição (considerando a estrutura):

 “A framework is a reusable design of all or part of a system that is

represented by a set of abstract classes and the way their instances interact.”

 Frameworks definem a arquitetura (e o fluxo de controle) de uma

aplicação

 Definição (considerando o propósito):

 “A framework is the skeleton of an application that can be

(48)

Frameworks: Inversão de Controle

 Mohamed Fayad and Douglas C. Schmidt. Object-Oriented

Application Frameworks. CACM, vol. 40, No. 10, October 1997.

 Componentes (bibliotecas de classes, de funções etc) são passivos:

threads próprias de uma aplicação decidem quando e como chamar os métodos de componentes

 Frameworks são ativos: possuem sua própria thread de controle, a

qual é responsável por chamar métodos da aplicação

 Inversão de controle: código da aplicação é chamado por código

interno do framework

 Princípio de Hollywood: “don't call us, we'll call you.''

 É comum frameworks incluírem o método main da aplicação

 Escreve-se apenas o código que é chamado pelo método main

 Diversos padrões de projeto suportam inversão de controle  Exemplos: Factory, Observer, Strategy etc

(49)

Frameworks: Exemplo

 Aplicação gráfica usando o framework Swing de Java:

public class SwingApplication implements ActionListener { ...

JButton button = new JButton("I'm a Swing button!"); button.addActionListener(this);

....

public void actionPerformed(ActionEvent e) { numClicks++;

label.setText(labelPrefix + numClicks); }

}

(50)

Frameworks: Caixa Branca e Preta

 Frameworks caixa-branca:

 Formados por componentes abstratos

 Instanciados por meio de herança e implementação de interfaces  Possibilitam maior flexibilidade

 Demandam maior conhecimento dos componentes utilizados

 Frameworks caixa-preta:

 Constituídos por componentes concretos  Instanciados por meio de composição

 Não demandam grande conhecimento sobre os componentes

 Apresentam menor flexibilidade que os sistemas caixa-branca

 Exemplo: frameworks para construção de GUI

 Frameworks caixa-cinza:

(51)

Frameworks: Caixa Branca e Preta

 Ralph E. Johnson. Components, frameworks, patterns. ACM

SIGSOFT Software Engineering Notes, p.10-17, vol. 22, n. 3, 1997.

 “If application programmers can use a framework by connecting

components together without having to look at their implementation then the framework is a black-box framework.”

 “Frameworks that rely on inheritance usually require more

knowledge on the part of developers, and so are called white-box.”

 “Black-box frameworks are easier to learn to use, but white-box

frameworks are often more powerful in the hands of experts.”

 “But black-box and white-box frameworks are a spectrum, not a

dichotomy. It is common for a framework to be used in a black-box way most of the time, and to be extended when the occasion

demands.”

 “If a framework is black-box enough, it is used just by instantiating

(52)

Frameworks: Caixa Branca e Preta

“In white box frameworks, also called architecture-driven

frameworks, instantiation is only possible through the creation of new classes.”

“Black box frameworks produce instances using configuration

scripts. Following configuration, an instantiation automation tool creates the classes and source code. For example, it is possible to use a graphical wizard that guides the user step by step through a framework instantiation process.”

(53)

Patterns

 “A pattern describes a problem to be solved, a solution, and the

context in which that solution works. It names a technique and describes its costs and benefits. Developers who share a set of patterns have a common vocabulary for describing their designs, and also a way of making design tradeoffs explicit. Patterns are

supposed to describe recurring solutions that have stood the test of time.”

 “The patterns in the book Design Patterns are closely related to

frameworks in another way. These patterns were discovered by examining a number of frameworks, and were chosen as being representative of reusable, object-oriented software.”

 “A single framework usually contains many patterns, so these

patterns are smaller than frameworks.”

 “Design patterns are the micro-architectural elements of

Referências

Documentos relacionados

Local de realização da avaliação: Centro de Aperfeiçoamento dos Profissionais da Educação - EAPE , endereço : SGAS 907 - Brasília/DF. Estamos à disposição

De seguida, vamos adaptar a nossa demonstrac¸ ˜ao da f ´ormula de M ¨untz, partindo de outras transformadas aritm ´eticas diferentes da transformada de M ¨obius, para dedu-

Código Descrição Atributo Saldo Anterior D/C Débito Crédito Saldo Final D/C. Este demonstrativo apresenta os dados consolidados da(s)

A baixa taxa de desconto ao longo dos anos de produção do campo, para o cálculo da função objetivo, aliada a baixa produção de água que a locação de

Este artigo está dividido em três partes: na primeira parte descrevo de forma sumária sobre a importância do museu como instrumento para construção do conhecimento, destaco

Por último, temos o vídeo que está sendo exibido dentro do celular, que é segurado e comentado por alguém, e compartilhado e comentado no perfil de BolsoWoman no Twitter. No

Após a fase de instrução a Comissão deverá elaborar relatório minucioso, indicando as peças principais dos autos, as provas em que se baseou para formar

Changes in the gut microbiota appears to be a key element in the pathogenesis of hepatic and gastrointestinal disorders, including non-alcoholic fatty liver disease, alcoholic