Introduction to Software Engineering · Introduction to Software Engineering Dr. Michael Eichberg...
Transcript of Introduction to Software Engineering · Introduction to Software Engineering Dr. Michael Eichberg...
Introduction to Software Engineering (2+1 SWS)Winter Term 2009 / 2010 Dr. Michael EichbergVertretungsprofessur Software EngineeringDepartment of Computer ScienceTechnische Universität Darmstadt
Introduction to Software Engineering
Dr. Michael EichbergFachgebiet Software EngineeringDepartment of Computer ScienceTechnische Universität Darmstadt
The IteratorDesign PatternFor details see Gamma et al. in “Design Patterns”
|The GoF Design Patterns
The Iterator Design PatternExample / Motivation
3
paragraph
Image
Document
paragraph
paragraph
paragraph
paragraph
Table
Issue: Processing the Document• We need a way to traverse
through the structure of a document to do, e.g., spell checking on each element of the document
• The traversal should not depend on the internal aggregation mechanism used for composite classes like a paragraph or row(e.g. an array of children vs. linked list of children)
|The GoF Design Patterns
The Iterator Design PatternExample / Motivation - Document Structure
4
paragraph
Image
Document
paragraph
paragraph
paragraph
paragraph
Table
IssueProcessing the Document
DocumentElement
Image
Group
Table
Document
Character
Row
Column
|The GoF Design Patterns
The Iterator Design PatternExample / Motivation - Processing the Document Structure1. Solution
5
paragraph
Image
Document
paragraph
paragraph
paragraph
paragraph
Table
IssueProcessing the Document
DocumentElement
getChild(int)getNumOfChildren() : int
Group
Define a getChild(int) operation that returns the child at a specified index. Issues:▶ Inefficient if children are kept in a linked
list▶ The interface should not assume certain
implementations
|The GoF Design Patterns
The Iterator Design PatternExample / Motivation - Processing the Document Structure2. Solution (Generalizing the Traversal)
6
paragraph
Image
Document
paragraph
paragraph
paragraph
paragraph
Table
IssueProcessing the Document
DocumentElement
currentElement() : DocumentElement void first();void next();boolean isDone();
Group
▶ More general interface defining linear access▶ Any container implementation will do equally well▶ Even streams - calculating elements as they are requested - are possible
Evaluation
Structure
|The GoF Design Patterns
The Iterator Design PatternExample / Motivation - Processing the Document StructureDemo
7
paragraph
Image
Document
paragraph
paragraph
paragraph
paragraph
Table
IssueProcessing the Document
▶ currentElement() - returns the “current” element
▶ first() - sets “current” to the first element▶ next() - sets “current” to the next element ▶ isDone() - returns true if the last element
has been reached
void draw(Group group) { DocumentElement elem; group.first(); while (!group.isDone()) { elem = group.currentElement(); elem.draw(); group.next(); } }
|The GoF Design Patterns
The Iterator Design PatternExample / Motivation Processing the Document Structure using Iterator Objects
8
DocumentElement
currentElement() : DocumentElement void first();void next();boolean isDone();
Group
currentElement() : DocumentElement void first();void next();boolean isDone();
GroupIterator
!Each individual GroupIterator object maintains its own reference to the current element.
Advantages▶ Multiple simultaneous iterations possible▶ Group relieved from iteration functionality
|The GoF Design Patterns
The Iterator Design PatternStructure
9
▶ The iterator type is transparent to the Client.▶ createIterator() is a factory method.
createIterator()
Aggregate
createIterator() ConcreteAggregate
first()next()isDone() : booleancurrentItem() : T
IteratorClient
T
ConcreteIterator
«method»return new ConcreteIterator();
|The GoF Design Patterns
The Iterator Design PatternParticipants
10
createIterator()
Aggregate
createIterator() ConcreteAggregate
first()next()isDone() : booleancurrentItem() : T
IteratorClient
T
ConcreteIterator
«method»return new ConcreteIterator();
▶ Iterator Defines an abstract interface for traversing aggregates.
▶ ConcreteIterator Provides a concrete implementation of the Iterator interface based on a particular ConcreteAggregate. Keeps track of the current position in the aggregate.
▶ Aggregate Defines an interface for iterator creation.
▶ ConcreteAggregate Maintains an aggregation of element objects and implements the Iterator creation function to return a ConcreteIterator.
|The GoF Design Patterns
The Iterator Design PatternConsequences
11
createIterator()
Aggregate
createIterator() ConcreteAggregate
first()next()isDone() : booleancurrentItem() : T
IteratorClient
T
ConcreteIterator
«method»return new ConcreteIterator();
▶ Abstract traversal of an aggregation Clients don’t know the internal representation of the aggregation.
▶ Iterators simplify the Aggregate interface Aggregates don’t have to supply traversal functions other than an iterator creation function.
▶ Supports variation on the traversal strategyConcrete iterators can provide different traversal mechanisms (e.g., going backwards though the aggregate).
▶ More than one traversal can be active on an aggregateEach iterator keeps track of its own position in the aggregate.
|The GoF Design Patterns
The Iterator Design PatternImplementation
12
createIterator()
Aggregate
createIterator() ConcreteAggregate
first()next()isDone() : booleancurrentItem() : T
IteratorClient
T
ConcreteIterator
«method»return new ConcreteIterator();
▶!Robust IteratorsWhen an element is removed from an aggregation, the Iterator might be pointing to an invalid current element.▶ Make a copy of the aggregate to be used for the iteration, so
elements may not be deleted.▶ Make the Iterator an Observer of the aggregation, so that it is
notified when elements are going to be deleted.▶ Additional Operations▶ skipTo▶ remove▶ previous▶ ...
|The GoF Design Patterns
The Iterator Design PatternImplementation - External vs. Internal Iteration
13
Provides a high degree of flexibility w.r.t. the iteration strategy.
Iterator i = Aggregate.createIterator();i.first();while (!i.isDone()) { System.out.println(i.currentItem()); i.next();}
Example
|The GoF Design Patterns
The Iterator Design PatternImplementation - External vs. Internal Iteration
14
Internal Iterators are particularly useful when access to the internal (private) state of an object is required or if the iteration logic is complex. But, comparing two data structures using internal iterators is nearly impossible.
public abstract class DocumentIterator { public DocumentIterator(Document doc) {…} public boolean traverse() {…}
public abstract processElement(DocumentElement elem);}
Example
|Placeholder
The Iterator Design PatternImplementation - NullIterator
•A NullIterator is always done•A NullIterator is a degenerate iterator to handle boundary
conditions; e.g., when traversing tree-structured aggregates and the “iterator” method should be placed in the Component interface (cf. Composite Pattern)
15
|Placeholder
The Iterator Design PatternRelated Patterns
•CompositeIterators are often applied to recursive structures such as composites• Factory Method
Polymorphic iterators rely on factory methods to instantiate the appropriate Iterator subclasses
16