Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Padres de Projeto
Roberto S. Bigonha 06 de novembro de 2008
Todos os direitos reservados Proibida a cpia sem autorizao do autor
Padres GoF
Abstract Factory Adapter Builder Bridge Chain-of-Responsability Command Composite Decorator Factory Method Faade Flyweight Interpreter
@Roberto S. Bigonha Padres de Projeto
Iterator Mediator Memento Observer Prototype Proxy Strategy Singleton State Template Method Visitor
C++
Padres de Projeto
Projeto de sistemas OO uma atividade complexa e difcil Projetar software OO reusvel ainda mais difcil Projetistas experientes resam solues desenvolvidas em outros projetos Sistemas OO bem estruturados tm padres recorrentes de classes e objetos
@Roberto S. Bigonha
Padres de Projeto
C++
Padres de Projeto
So solues recorrentes para um problema em um dado contexto Capturam a experincia de desenvolvimento de software So arquiteturas comprovadas para construir software orientado por objetos flexvel e mais extensvel. Cada padro fornece uma soluo para um problema comum no projeto de software
@Roberto S. Bigonha Padres de Projeto C++ 4
@Roberto S. Bigonha
Padres de Projeto
C++
Press, 1996. Martin Fowler, Analysis Patterns: Reusable Object Models, Addison-Wesley, 1997. Alan Shalloway and James R. Trott, Design Patterns Explained, Addison-Wesley, 2001. Steven John Metsker, Design Patterns Java Worlbook, Addison-Wesley, 2001
@Roberto S. Bigonha Padres de Projeto C++ 8
@Roberto S. Bigonha
Padres de Projeto
C++
10
@Roberto S. Bigonha
Padres de Projeto
C++
11
Padres Estruturais Permitem organizar classes e objetos em estruturas maiores: Proxy, Adapter, Bridge, Composite,
Decorator, Faade, Flyweight
ClasseAbstrata AssinaturasOps( )
criao agregao
@Roberto S. Bigonha
Padres de Projeto
C++
13
Padres de Criao
@Roberto S. Bigonha
Padres de Projeto
C++
14
@Roberto S. Bigonha
Padres de Projeto
C++
15
Padro Singleton
@Roberto S. Bigonha
Padres de Projeto
C++
16
@Roberto S. Bigonha
Padres de Projeto
C++
17
Singleton
return uniqueInstance
@Roberto S. Bigonha
Padres de Projeto
C++
18
@Roberto S. Bigonha
Padres de Projeto
C++
19
Padro Singleton I
class Singleton { static Singleton* theInstance; Singleton ( ) { } Singleton& operator=(Singleton&); Singleton(const Singleton&); public: static Singleton* instance( ); Operaes normais da classe, e.g., void f( ); }; Singleton* Singleton::theInstance = 0; Singleton* Singleton::instance( ){ if (theInstance==0) theInstance=new Singleton(); return theInstance; }
@Roberto S. Bigonha Padres de Projeto C++ 21
@Roberto S. Bigonha
Padres de Projeto
C++
22
Problemas
int main( ) { Singleton* s1 = Singleton::instance( ); Singleton* s2 = Singleton::instance( ); if (s1 != s2) cout << "No devia acontecer!"; else cout << "Funciona!"; delete s1; // ?????? s2->f( ); // Exceo!? }
@Roberto S. Bigonha
Padres de Projeto
C++
23
@Roberto S. Bigonha
Padres de Projeto
C++
24
@Roberto S. Bigonha
Padres de Projeto
C++
26
@Roberto S. Bigonha
Padres de Projeto
C++
27
Todos os elementos de x referenciam mesmo objeto No se sabe que subclasses sero instanciadas!
@Roberto S. Bigonha Padres de Projeto C++ 29
Problemas
MazeFactory* MazeFactory::instance(string s) { if (theInstance == 0) { if (s == mgico) theInstance = new MagicFactory( ); else if (s == agent) theInstance = new StdFactory( ); else theInstance = new DefaultFactory( ); } return theInstance; }
@Roberto S. Bigonha
Padres de Projeto
C++
32
Mais Problemas
Construtoras das subclasses de MazeFactory so pblicas Pode-se, ento, criar diretamente mais de uma instncia de subclasses de MazeFactory:
void g( ) { ... MagicFactory* x = new MagicFactory( ); ... }
@Roberto S. Bigonha
Padres de Projeto
C++
34
@Roberto S. Bigonha
Padres de Projeto
C++
39
@Roberto S. Bigonha
Padres de Projeto
C++
40
@Roberto S. Bigonha
Padres de Projeto
C++
41
Product
product = factoryMethod()
ConcreteProduct
AnotherFactory factoryMethod( )
@Roberto S. Bigonha
Padres de Projeto
C++
42
@Roberto S. Bigonha
Padres de Projeto
C++
43
Problemas
Mtodo createMaze muito inflexvel Se quisermos criar outro tipo de jogo de labirinto, com EnchantedRooms e EnchantedDoors, createMaze( ) dever ser modificado Como ento reprojetar createMaze de forma a tornar fcil a criao de outros jogos? Como tornar createMaze um mtodo fechado para modificaes (princpio OCP)? Soluo: adicionar Mtodos de Fabricao MazeGame.
@Roberto S. Bigonha
Padres de Projeto
C++
46
@Roberto S. Bigonha
Padres de Projeto
C++
47
@Roberto S. Bigonha
Padres de Projeto
C++
48
@Roberto S. Bigonha
Padres de Projeto
C++
49
Constri Salas r1 e r2
Door* door = makeDoor(r1,r2); r1->setside(NORTH, r1->setside(SOUTH, r1->setside(EAST, r1->setside(WEST, r2->setside(NORTH, r2->setside(SOUTH, r2->setside(EAST, r2->setside(WEST,
@Roberto S. Bigonha
Padres de Projeto
} };
@Roberto S. Bigonha Padres de Projeto C++ 51
@Roberto S. Bigonha
Padres de Projeto
C++
53
@Roberto S. Bigonha
Padres de Projeto
C++
54
AbstractProductB
ProductB1
ProductB2
@Roberto S. Bigonha
Padres de Projeto
C++
55
@Roberto S. Bigonha
Padres de Projeto
C++
56
@Roberto S. Bigonha
Padres de Projeto
C++
57
maze->addRoom(r2);
Constri Salas r1 e r2
Door* door = factory->makeDoor(r1,r2); r1->setside(NORTH, factory->makeWall( ) ); r1->setside(SOUTH, factory->makeWall( ) ); r1->setside(EAST, door ); r1->setside(WEST, factory->makeWall( ) ); r2->setside(NORTH, r2->setside(SOUTH, r2->setside(EAST, r2->setside(WEST, factory->makeWall( ) ); factory->makeWall( ) ); factory->makeWall( ) ); door );
@Roberto S. Bigonha
Padres de Projeto
C++
59
@Roberto S. Bigonha
Padres de Projeto
C++
61
Observaes
Agora createMaze com Abstract Factory muito mais flexvel createMaze delega a responsabilidade de criao de objetos ao objeto de tipo MazeFactory Estrutura garante que somente objetos de uma famlia podem ser criados Novos tipos de produtos para a mesma fbrica demanda reprogramao Novas fbricas dentro da mesma hierarquia podem ser facilmente incorporadas
@Roberto S. Bigonha
Padres de Projeto
C++
62
@Roberto S. Bigonha
Padres de Projeto
C++
63
Fbricas de Widgets
Problema: Na construo de interfaces GUI, deseja-se criar Widgets, por exemplo, janelas, botes e barras de rolagem Solues: Soluo 1: usando mtodos de fabricao (no mostrada, fica para o aluno) Soluo 2: usando fbricas e herana Soluo 3: usando fbricas e composio
@Roberto S. Bigonha Padres de Projeto C++ 64
@Roberto S. Bigonha
Padres de Projeto
C++
65
class WidgetFactory { public: virtual Window createWindow( )= 0 ; virtual ScrollBar createScrollBar( )=0; virtual Button createButton( ) = 0; };
@Roberto S. Bigonha Padres de Projeto C++ 66
Padres de Projeto
C++
68
@Roberto S. Bigonha
Padres de Projeto
C++
69
@Roberto S. Bigonha
Padres de Projeto
C++
71
@Roberto S. Bigonha
Padres de Projeto
C++
72
Padres Estruturais
@Roberto S. Bigonha
Padres de Projeto
C++
74
@Roberto S. Bigonha
Padres de Projeto
C++
75
Padro Proxy
@Roberto S. Bigonha
Padres de Projeto
C++
76
@Roberto S. Bigonha
Padres de Projeto
C++
77
@Roberto S. Bigonha
Padres de Projeto
C++
78
Subject request( )
rs
rs->request( )
aRealSubject
@Roberto S. Bigonha
Padres de Projeto
C++
79
@Roberto S. Bigonha
Padres de Projeto
C++
80
@Roberto S. Bigonha
Padres de Projeto
C++
81
@Roberto S. Bigonha
Padres de Projeto
C++
82
};
@Roberto S. Bigonha Padres de Projeto C++ 83
}
@Roberto S. Bigonha Padres de Projeto C++ 84
Para ter a sincronizao desejada, deve-se usar a classe Proxy em vez de TheTable
@Roberto S. Bigonha Padres de Projeto C++ 85
@Roberto S. Bigonha
Padres de Projeto
C++
86
x = realTable->getElementAt(row,col);
pthread_mutex_unlock(&lock[row]); return x; }
@Roberto S. Bigonha
Padres de Projeto
C++
87
pthread_mutex_lock(&locks[row]);
realTable->setElementAt(element,row,col);
pthread_mutex_unlock(&lock[row]);
}
@Roberto S. Bigonha
Padres de Projeto
C++
88
@Roberto S. Bigonha
Padres de Projeto
C++
89
@Roberto S. Bigonha
Padres de Projeto
C++
90
Mas este mtodo pode bloquear toda a tabela por longo tempo, comprometendo performance
@Roberto S. Bigonha Padres de Projeto C++ 91
Mas a clonagem pode bloquear toda a tabela por longo tempo, comprometendo performance
@Roberto S. Bigonha Padres de Projeto C++ 92
@Roberto S. Bigonha
Padres de Projeto
C++
93
@Roberto S. Bigonha
Padres de Projeto
C++
94
@Roberto S. Bigonha
Padres de Projeto
C++
95
@Roberto S. Bigonha
Padres de Projeto
C++
96
@Roberto S. Bigonha
Padres de Projeto
C++
97
pthread_mutex_lock(&lockWrite) ;
*copy = *theHashTable; copy->put(key, value, n);
Padro Adapter
@Roberto S. Bigonha
Padres de Projeto
C++
99
Target request( )
Adaptee specificRequest( )
Adapter request( )
adaptee adaptee->specificRequest()
@Roberto S. Bigonha
Padres de Projeto
C++
101
client
Target Request ( )
Adaptee specificRequest( )
Adapter request( )
specificRequest( )
@Roberto S. Bigonha
Padres de Projeto
C++
102
Jogo de Pinos
@Roberto S. Bigonha
Padres de Projeto
C++
103
Jogo de Pinos
O clssico jogo de pinos redondos e quadrados que devem ser encaixados em um tabuleiro Suponha inicialmente que somente haja uma classe para cada tipo de pino: classe SquarePeg classe RoundPeg Seja PegBoard o tabuleiro de pinos quadrados Deseja-se inserir ambos os tipos de pinos da mesma forma
@Roberto S. Bigonha
Padres de Projeto
C++
104
Adaptador Unidirecional
@Roberto S. Bigonha
Padres de Projeto
C++
105
@Roberto S. Bigonha
Padres de Projeto
C++
109
Adaptador Bidirecional
@Roberto S. Bigonha
Padres de Projeto
C++
110
@Roberto S. Bigonha
Padres de Projeto
C++
111
@Roberto S. Bigonha
Padres de Projeto
C++
112
@Roberto S. Bigonha
Padres de Projeto
C++
116
Padro Composite
@Roberto S. Bigonha
Padres de Projeto
C++
117
Leaf operation( )
@Roberto S. Bigonha
Padres de Projeto
C++
119
@Roberto S. Bigonha
Padres de Projeto
C++
120
@Roberto S. Bigonha
Padres de Projeto
C++
121
Questes de Implementao
O objeto composto conhece os objetos que o compem, isto , seus filhos Os filhos devem conhecer o componente pai? depende da aplicao Onde os mtodos de administrao dos filhos (add, remove, getChild) devem ser declarados? na classe Component : mais transparente na classe Composite: mais seguro
@Roberto S. Bigonha
Padres de Projeto
C++
122
@Roberto S. Bigonha
Padres de Projeto
C++
123
@Roberto S. Bigonha
Padres de Projeto
C++
124
Janelas
@Roberto S. Bigonha
Padres de Projeto
C++
126
Exemplo 1: Janelas
Um sistema GUI tem objetos janela (Window) que podem conter vrios componentes GUI (widgets), tais como botes, reas de texto, etc A janela pode tambm conter contineres widget, que contm outros widgets Soluo 1: cada widget tem uma interface prpria para atualizar a janela mtodo update de Window atualiza cada componente
@Roberto S. Bigonha
Padres de Projeto
C++
127
Soluo 1: Janelas
class Window { Button* buttons; TextArea* textAreas; Menu* menus; WidgetContainer* containers; public: ... void update( ) { .... for (int k = 0 ; k < buttonsLen; k++) buttons[k]->draw( ); for (int k = 0 ; k < menusLen; k++) menus[k]->refresh( ); for (int k = 0 ; k < containersLen; k++) containers[k]->updateWidgets( ); ... } ... };
@Roberto S. Bigonha Padres de Projeto C++ 128
Soluo 2: Janelas
Soluo 1 viola o Princpio do Aberto-Fechado: Se desejarmos adicionar um componente de um novo tipo, deveremos modificar o mtodo update Soluo 2: Programar com base na interface Todos widgets (Button, Menu, TextArea, etc) implementam a mesma interface Widget Mas ainda ser mantida diferena entre widget e containers de widgets
@Roberto S. Bigonha Padres de Projeto C++ 129
Soluo 2: Janela
public class Window { Widget* widgets; WidgetContainer* containers; public: ... void update( ) { ... for (int k = 0 ; k < widgetsLen; k++) widgets[k]->update( ); for (int k = 0 ; k < containersLen; k++) containers[k]->updateWidgets(); ... } ... };
@Roberto S. Bigonha Padres de Projeto C++ 130
@Roberto S. Bigonha
Padres de Projeto
C++
131
@Roberto S. Bigonha
Padres de Projeto
C++
132
@Roberto S. Bigonha
Padres de Projeto
C++
133
Padro Decorator
@Roberto S. Bigonha
Padres de Projeto
C++
134
@Roberto S. Bigonha
Padres de Projeto
C++
135
@Roberto S. Bigonha
Padres de Projeto
C++
136
@Roberto S. Bigonha
Padres de Projeto
C++
137
Motivao
Decoradores so uma alternativa flexvel a especializao de classe til quando especializao for impraticvel devido: possibilidade de se gerar muitas extenses necessidade de se ter um grande nmero de subclasses para suportar as combinaes possveis
@Roberto S. Bigonha
Padres de Projeto
C++
138
Motivao - Exemplo
Suponha que se deseja adicionar bordas e barras de rolagem a um componente GUI H 3 tipos de bordas: Plain 3D Fancy H dois tipos de barras de rolagem: Horizontal Vertical Portanto h 15 combinaes possveis
@Roberto S. Bigonha Padres de Projeto C++ 139
@Roberto S. Bigonha
Padres de Projeto
C++
141
@Roberto S. Bigonha
Padres de Projeto
C++
143
Estrutura de Decorator
Component operation( )
ConcreteComponent operation( )
Decorator
component component.operation()
operation( )
super.operation( ); addedBehavior( )
C++ 149
Padro Faade
@Roberto S. Bigonha
Padres de Projeto
C++
150
@Roberto S. Bigonha
Padres de Projeto
C++
152
@Roberto S. Bigonha
Padres de Projeto
C++
153
@Roberto S. Bigonha
Padres de Projeto
C++
154
Padres Comportamentais
@Roberto S. Bigonha
Padres de Projeto
C++
155
@Roberto S. Bigonha
Padres de Projeto
C++
156
Padro Memento
@Roberto S. Bigonha
Padres de Projeto
C++
157
@Roberto S. Bigonha
Padres de Projeto
C++
158
Padro State
@Roberto S. Bigonha
Padres de Projeto
C++
159
TCPConnection opera conforme seu estado corrente Objetos State tm as mesmas operaes do Original
@Roberto S. Bigonha Padres de Projeto C++ 161
State handle( )
State->handle()
ConcreteStateA handle ( )
ConcreteStateB handle( )
@Roberto S. Bigonha
Padres de Projeto
C++
162
Padro State
@Roberto S. Bigonha
Padres de Projeto
C++
163
Padro State
@Roberto S. Bigonha
Padres de Projeto
C++
164
Padro State
@Roberto S. Bigonha
Padres de Projeto
C++
165
Padro Chain-of-Responsability
@Roberto S. Bigonha
Padres de Projeto
C++
166
Padro Chain-of-Responsability
Permite determinar, durante a execuo, o objeto que ir tratar uma dada mensagem Mensagem enviada a um objeto que pode tratar a mensagem ou pass-la para o prximo na cadeia Exemplos: PABX com vrias linhas: a primeira linha disponvel faz o atendimento Help em interface grfica (clique no component): se h help para componente, ele exibido, seno exibe-se o help daquele que o contm helps organizados do mais especfico para o mais geral objeto que prov o help no conhecido daquele que inicia o pedido
@Roberto S. Bigonha Padres de Projeto C++ 167
Motivao do Chain-of-Responsability
Todo objeto da cadeia conhece seu sucessor Todos os objetos da cadeia devem ter mesma interface
@Roberto S. Bigonha Padres de Projeto C++ 168
Estrutura do Chain-of-Responsability
Client successor
Handler handleRequest()
ConcreteHandler2 handleRequest( )
aConcreteHandler sucessor
Padres de Projeto C++
aConcreteHandler sucessor
169
@Roberto S. Bigonha
Padro Command
@Roberto S. Bigonha
Padres de Projeto
C++
170
Client
Invoker
Receiver action( )
receiver
receiver->action( )
Invoker = uma classe da ferramenta, e.g., menuItem Receiver= classe da aplicao que realiza a ao desejada
@Roberto S. Bigonha Padres de Projeto C++ 172
@Roberto S. Bigonha
Padres de Projeto
C++
173
@Roberto S. Bigonha
Padres de Projeto
C++
174
Task Minder
Deseja-se implementar uma classe que periodicamente executa um ou mais mtodos de vrios objetos Por exemplo, deseja-se criar uma classe para fazer uma operao de backup a cada hora e uma verificao do status do disco a cada 10 minutos A classe no deve conhecer detalhes destas operaes Soluo: Desacoplar a classe que escalona as operaes da classe que realiza as operaes
@Roberto S. Bigonha Padres de Projeto C++ 175
@Roberto S. Bigonha
Padres de Projeto
C++
176
Tasks
class Task { public: virtual void performTask( ) = 0; }; class BackUpTask: public Task { public: BackUpTask ( ) { } void performTask( ){...dispara ao da task...} }; class StatusTask: public Task { public: StatusTask ( ) { } void performTask( ){...dispara ao da task...} };
@Roberto S. Bigonha Padres de Projeto C++ 177
TaskEntry
class TaskEntry { Task* task; long lastDone; long interval; public: TaskEntry(Task* task, long interval); Task* getTask( ); void setTask(Task* task); long getInterval( ); long setInterval(long ri); long getLastDone( ); void setLastDone(long t); };
@Roberto S. Bigonha Padres de Projeto C++ 178
TaskEntry ...
TaskEntry::TaskEntry(Task*task,long interval){ this->task = task; this->interval = interval; this->lastdone = currentSystemTime( ); } Task* TaskEntry::getTask( ) {return task;} void TaskEntry::setTask(Task* task){ this->task = task; }
@Roberto S. Bigonha
Padres de Projeto
C++
179
TaskEntry ...
long TaskEntry::getInterval( ){ return interval; } long TaskEntry::setInterval(long ri){ this->interval= ri; } long TaskEntry::getLastDone( ){ return LastDone; } void TaskEntry:: setLastDone(long t){ lastDone = t; }
@Roberto S. Bigonha Padres de Projeto C++ 180
TaskMinder
class TaskMinder: { long sleepInterval; Vector<TaskEntry*> taskList; public: typedef Vector<TaskEntry*>::iterator Enum; TaskMinder(long sleepInterval,int maxTasks); void addTask(Task* task,long interval); long getSleepInterval( ); void setSleepInterval(long s); void* minder(void* unused); };
@Roberto S. Bigonha
Padres de Projeto
C++
182
TaskMinder ...
TaskMinder::TaskMinder(long sleepInterval, int maxTasks){ this->sleepInterval = sleepInterval; tasklist = new Vector<TaskEntry*>(maxTasks); create_and_start_thread(&minder); } long TaskMinder::getSleepInterval( ){ return sleepInterval; } void TaskMinder::setSleepInterval(long sleep){ sleepInterval = sleep; }
@Roberto S. Bigonha Padres de Projeto C++ 183
TaskMinder ...
void TaskMinder::addTask(Task* task, long interval) { long i = (interval > 0) ? interval : 0; TaskEntry* t = new TaskEntry(task,i); tasklist.addElement(t); }
@Roberto S. Bigonha
Padres de Projeto
C++
184
Padro Observer
@Roberto S. Bigonha
Padres de Projeto
C++
186
@Roberto S. Bigonha
Padres de Projeto
C++
188
@Roberto S. Bigonha
Padres de Projeto
C++
189
Observer update(Subject* )
subject
return subjectState
@Roberto S. Bigonha Padres de Projeto
observerState = subject->getState( )
C++ 190
@Roberto S. Bigonha
Padres de Projeto
C++
191
@Roberto S. Bigonha
Padres de Projeto
C++
192
Observadores de Temperatura
Subject addObserver(Observer*) removeObserver(Observer*) notifyObservers( ) observers
Observer
update(Subject*) {abstract}
CelsiusTermometer update(Subject*)
C++
194
@Roberto S. Bigonha
Padres de Projeto
C++
195
A Classe de Um Observado
class Temperature: public Subject { double value; public: Temperature(double v):value(v){ } double getValue() { return value; } void setValue(double value) { this->value = value; notifyObservers( ); } };
@Roberto S. Bigonha Padres de Projeto C++ 196
Um Observador
class CelsiusTermometer: public Observer { public: void update(Subject* s) { Temperature* t = dynamic_cast<Temperature*>(s); double value = t->getValue( ); printf("Celsius: %d", value); } };
@Roberto S. Bigonha
Padres de Projeto
C++
197
Outro Observador
class FahrenheitTermometer: public Observer{ public: void update(Subject* s){ Temperature* t = dynamic_cast<Temperature*>(s); double value = 1.8*t->getValue() + 32; printf(Fahrenheit: %d",value); } };
@Roberto S. Bigonha
Padres de Projeto
C++
198
Padro Strategy
@Roberto S. Bigonha
Padres de Projeto
C++
199
@Roberto S. Bigonha
Padres de Projeto
C++
200
@Roberto S. Bigonha
Padres de Projeto
C++
202
Strategy algorithmInterface( )
ConcreteStrategyA algorithmInterface( )
ConcreteStrategyB algorithmInterface( )
ConcreteStrategyC algorithmInterface( )
@Roberto S. Bigonha
Padres de Projeto
C++
203
@Roberto S. Bigonha
Padres de Projeto
C++
204
SortStategy
class SortArray { SortStrategy* sortStrategy; public: SortArray(SortStrategy* s) { this->sortStrategy = s; } SetSortStrategy(SortStrategy* s) { this->sortStrategy = s; } virtual void sort(int a[]){ sortStrategy->sort(a); } };
@Roberto S. Bigonha Padres de Projeto C++ 205
SortStategy
class SortStrategy { public: sort(int a[ ]) = 0 }; class BubbleSort: public SortStrategy { public: sort(int a[ ]) { ... } }; class QuickSort : public SortStrategy { public: sort(int a[ ]) { ... } };
@Roberto S. Bigonha Padres de Projeto C++ 206
SortStategy
int main { BubbleSort* bs = new BubbleSort( ); QuickSort* qs = new QuickSort(); SortArray sa1(bs); SortArray sa2(qs); int a [ ] = {...}; int b [ ] = {...}; ...; sa1.setSortStrategy(qs); ... sa1.sort(a); sa2.sort(b); }
@Roberto S. Bigonha Padres de Projeto C++ 207
@Roberto S. Bigonha
Padres de Projeto
C++
208
@Roberto S. Bigonha
Padres de Projeto
C++
209
@Roberto S. Bigonha
Padres de Projeto
C++
210
@Roberto S. Bigonha
Padres de Projeto
C++
212
primitiveOperation1( ) primitiveOperation2( )
templateMethod( )
primitiveOperation1( ) primitiveOperation2( )
@Roberto S. Bigonha
Padres de Projeto
C++
213
Padro Iterator
@Roberto S. Bigonha
Padres de Projeto
C++
219
Iterador deve ter acesso a representao do objeto continer do qual ele apresenta valores Neste caso, o Iterador uma classe friend do
continer
@Roberto S. Bigonha Padres de Projeto C++ 221
Client
ConcreteAgregate createIterator( )
ConcreteIterator
@Roberto S. Bigonha
Padres de Projeto
C++
223
@Roberto S. Bigonha
Padres de Projeto
C++
224
int main( ) { IntSet s = IntSet(1000); for (int i = 0; i <= 100 , i++) { s.insert(i); } try{ for (s.first( ); !s.isDone( ); s.next( ) ) { printf( "%d ", s.currentItem()); } } catch(Error){ ... } }
@Roberto S. Bigonha Padres de Projeto C++ 226
@Roberto S. Bigonha
Padres de Projeto
C++
227
Padro Iterador I
class IntSet { int max, *s, incr, last; public: IntSet(int m); friend class Iterator; void insert(int x); void remove(int x); int cardinalidade( ); bool in(int x); Iterator createIterator( ); };
@Roberto S. Bigonha
Padres de Projeto
C++
228
@Roberto S. Bigonha
Padres de Projeto
C++
229
@Roberto S. Bigonha
Padres de Projeto
C++
230
@Roberto S. Bigonha
Padres de Projeto
C++
231
Padro Iterador I
IntSet::Iterator::Iterator(IntSet* is):index(0){ this->is=is; }; void IntSet::Iterator::first( ) {index = 0;} void IntSet::Iterator::next( ) throw(Error){ if (index < is->max1) ++index; else throw Error(); } bool IntSet::Iterator::isDone( ) { return index == is->last; } int IntSet::Iterator::currentItem( ) { if (!isDone) return is->s[next]; throw Error(); }
@Roberto S. Bigonha Padres de Projeto C++ 232
Padro Iterador I
int main(String[ ] args) { IntSet s = IntSet(1000); IntSet::Iterador a = s.createIterador( ); IntSet::Iterador b = s.createIterador( ); for(int i=1; i<100 ; i++) {s.insert(i);} for(a.first( );!a.isDone( ); a.next( )){ int i = a.currentItem( ); for(b.first();!b.isDone );b.next( )){
int k = b.currentItem( );
@Roberto S. Bigonha
Padres de Projeto
C++
234
Padro Iterador II
template <class Item> class List { public: List(long size=1000); long count( ) const; Item& get(long index) const; ... }; template <class Item> class Iterator { public: virtual void first( ) = 0; virtual void next( ) = 0; virtual bool isDone( ) const = 0; virtual Item currentItem( ) const = 0; protected: Iterator( ); };
@Roberto S. Bigonha Padres de Projeto C++ 235
@Roberto S. Bigonha
Padres de Projeto
C++
236
@Roberto S. Bigonha
Padres de Projeto
C++
238
@Roberto S. Bigonha
Padres de Projeto
C++
240
@Roberto S. Bigonha
Padres de Projeto
C++
241
protected: Iterator( ); };
@Roberto S. Bigonha
Padres de Projeto
C++
242
@Roberto S. Bigonha
Padres de Projeto
C++
243
@Roberto S. Bigonha
Padres de Projeto
C++
245
@Roberto S. Bigonha
Padres de Projeto
C++
246
Padro Mediator
@Roberto S. Bigonha
Padres de Projeto
C++
249
@Roberto S. Bigonha
Padres de Projeto
C++
250
Padro Visitor
@Roberto S. Bigonha
Padres de Projeto
C++
251
@Roberto S. Bigonha
Padres de Projeto
C++
253
@Roberto S. Bigonha
Padres de Projeto
C++
254
Padro Visitor
class A:public z{...}; class B:public z{...};
fim
@Roberto S. Bigonha
Padres de Projeto
C++
257