iterator behavioural design pattern

25
Iterator behavioural Iterator behavioural design pattern design pattern Eivind J. Nordby University of Karlstad Inst. for Information Technology Dept. of Computer Science Last revised 051010

Upload: hazina

Post on 09-Jan-2016

30 views

Category:

Documents


0 download

DESCRIPTION

Iterator behavioural design pattern. Eivind J. Nordby University of Karlstad Inst. for Information Technology Dept. of Computer Science Last revised 051010. Introduction. An iterator can be used in order to - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Iterator behavioural design pattern

Iterator behavioural design Iterator behavioural design patternpattern

Eivind J. Nordby

University of Karlstad

Inst. for Information Technology

Dept. of Computer ScienceLast revised 051010

Page 2: Iterator behavioural design pattern

1998-09-15 Computer Science, University of

Karlstad2

Introduction Introduction

An iterator can be used in order to provide a way to access the elements of an

aggregate object sequentially without exposing its underlying representation

always used with ”containers” or ”collections”

Page 3: Iterator behavioural design pattern

1998-09-15 Computer Science, University of

Karlstad3

next()

The basic ideaThe basic idea

aContainer

anElement

anElement

anElement

anElement

anElement

anElement

aContainerIterator

+first()

+next()

+isDone()

+current()

current-Element*

”on” or “over”

isDone()

first()

current()

Page 4: Iterator behavioural design pattern

1998-09-15 Computer Science, University of

Karlstad4

Basic usageBasic usage

List* pMyList = new List;// populate the listListIterator *pli = new ListIterator(pMyList);

// Implicit or explicit: pli->first();while (!pli->isDone()) {

// do something with pli->current(); pli->next();}delete pli;

Page 5: Iterator behavioural design pattern

1998-09-15 Computer Science, University of

Karlstad5

Abstract iteratorsAbstract iterators

Page 6: Iterator behavioural design pattern

1998-09-15 Computer Science, University of

Karlstad6

Iterators: ConsequencesIterators: Consequences

They support variations in the traversal of an aggregate.– through polymorphic iteration

They simplify the Aggregate interface.– remove the iterator interface from aggregate

More than one traversal can be pending on an aggregate.

Page 7: Iterator behavioural design pattern

1998-09-15 Computer Science, University of

Karlstad7

Iterate Through the Positions of a Iterate Through the Positions of a Game BoardGame Board

low …

high…

… … … … … …

pci

pri

Page 8: Iterator behavioural design pattern

1998-09-15 Computer Science, University of

Karlstad8

MotivationsMotivations

Why positions and not fields?– Does not assume that there is a field

Use the iterator to populate the board with fields Use the iterator to print the fields

Why separate for columns and rows?– Allows to express explicitly the intention of the

iteration For instance row-wise printing Without knowing the implementation

Why a common base class (BoardIterator)– Same protocol for all iterators

Page 9: Iterator behavioural design pattern

1998-09-15 Computer Science, University of

Karlstad9

Example ClientExample Client

// <select a game, suppressed>

Board* myBoard;

myBoard = GameFactory::instance().createBoard();

// print the board row by row by

// iterating over the positions of the first column

BoardIterator *pci = myBoard->columnIterator();

while (!pci->isDone()) {

// do something at pci->current(), see next slide

pci->next(); // go on to the next game row

}

delete pci;

Page 10: Iterator behavioural design pattern

1998-09-15 Computer Science, University of

Karlstad10

do something with pci->current()do something with pci->current()

// iterate three times over the current row positions

const int drawRows = 3; // for each position

for (int i = 1; i <= drawRows; i++) {

BoardIterator *pri = myBoard->rowIterator(pci->current());

while (!pri->isDone()) {

out << myBoard->fieldAt(pri->current())->toString(i);

pri->next();

}

delete pri;

} OO style: create a new iterator object whenever needed rather than reusing the same

one– Simplifies logic and improves correctness

Page 11: Iterator behavioural design pattern

1998-09-15 Computer Science, University of

Karlstad11

Graphic alternativeGraphic alternative

For a graphic clientvoid paint(GraphicContext* gc){ Board* myBoard; myBoard = GameFactory::instance().createBoard(); myBoard->paint(gc); // iterating over the positions of the board BoardIterator *pbi = myBoard->defaultIterator(); while (!pbi->isDone()) { myBoard->fieldAt(pbi->current())->paint(gc); pbi->next(); } delete pci;} // paint

Page 12: Iterator behavioural design pattern

1998-09-15 Computer Science, University of

Karlstad12

A more realistic graphic wayA more realistic graphic way

In the previous example, each field needs to compute its own position on the graphic surface.

Normally, the graphic picture will consist of a lot of small views, one for each field– The board view paints the board frame– Each field view paints its field and piece– The paiting is inisialized from the operating system– No iterator is needed at all

Page 13: Iterator behavioural design pattern

1998-09-15 Computer Science, University of

Karlstad13

A more realistic graphic clientA more realistic graphic client

class BoardView{ Board* board; // assigned on creation void paint() {board->paint(this->graphicContext();}} // class BoarViewclass FieldView{ Field* field; void paint() { gc->foregroundColor(fgcOf(field->position()); gc->backgroundColor(bgcOf(field-’>position()); gc->inset(Point(1,1)); field->paint(this->graphicContext(); }

Page 14: Iterator behavioural design pattern

1998-09-15 Computer Science, University of

Karlstad14

A graphics aware modelA graphics aware model

class Field{

Piece* piece;

void paint(GraphicContext* gc){

if (piece!=0) piece->paint(gc);

gc->drawSquare(Point(0,0), gc->size());

}

} // class Field

class Piece{

Bitmap bitMap; // initialized at creation

void paint(GraphicContext* gc){gc->draw(bitMap);}

}

Page 15: Iterator behavioural design pattern

1998-09-15 Computer Science, University of

Karlstad15

ColumnIteratorColumnIterator

Iterate over the positions of a column– Defaults to the first column on the board– ColumnIterator(Board* board);

Alternative constructor for explicit start position– Iterate over a column starting from a given

position– ColumnIterator(Board* board, Point position);

Page 16: Iterator behavioural design pattern

1998-09-15 Computer Science, University of

Karlstad16

ColumnIterator FeaturesColumnIterator Features Constructors

– ColumnIterator(Board* board) // Pre: board not null

– ColumnIterator(Board* b, Point pos) // Pre: b not null

Accessors– Point current() // Post: result = current position

– bool isDone() // Post: result = current not inside board

Transformers– void next() // Post: current stepped to next position

Page 17: Iterator behavioural design pattern

1998-09-15 Computer Science, University of

Karlstad17

Abstract BoardIteratorAbstract BoardIterator RowIterator and ColumnIterator share

– the same protocol– the same constructors– the same implementation

except for the function next()

They are obvious candidates to share– a common (abstract/default) base class– the derived classes (re)define next()

Some ideas follow

Page 18: Iterator behavioural design pattern

1998-09-15 Computer Science, University of

Karlstad18

Conceptual ModelConceptual Model

positions

*

+current1

* 1

iterates over

Board

+fieldAt:Field+contains:bool+low:Point+high:Point+size:Point

RowIterator

+next:void

PointColumnIterator

+next:void

BoardIterator

+isDone:bool+next:void

Page 19: Iterator behavioural design pattern

1998-09-15 Computer Science, University of

Karlstad19

A Possible ImplementationA Possible Implementation

Assume the following Access methods for Board:

– Field* fieldAt(Point position);– Point low(); // lowest position– Point high(); // highest position– Point size(); // dimensions– bool contains(Point position);

Access methods for Field:– Point position();– Board *board();

Page 20: Iterator behavioural design pattern

1998-09-15 Computer Science, University of

Karlstad20

Design modelDesign model

_high

1

_low

1

_board

1

_current!

0..1

_position

_board

*0..1

ColumnIterator

+next:void

RowIterator

+next:void

Point

+x:int+y:int+incX:void+incY:void+setX:void+setY:void

Board

+fieldAt:Field+contains:bool+low:Point+high:Point+size:Point

BoardIterator

+isDone:bool+current:Point+next:void

Field

+toString:String

Page 21: Iterator behavioural design pattern

1998-09-15 Computer Science, University of

Karlstad21

class BoardIteratorclass BoardIterator Private instance variables

Point _current; // the current posBoard* _pBoard; // != null

Implementation invariant– _current.x() is fixed, identifies the

column– _current.y() is the current row number– *_pBoard is the board iterated over

Constructor(Board *board) // board != nullBoardIterator(Board *board) { _current = board->low(); _pBoard = board}

Page 22: Iterator behavioural design pattern

1998-09-15 Computer Science, University of

Karlstad22

class BoardIterator (cont’d)class BoardIterator (cont’d)

Public iterator access functions// void first() {_current.setY(board->low().y());}void next() {<move to next in some default order>}boolean isDone() {return !inside(_current);}Point current() {return _current;}

private:bool inside(Point position){

return board->contains(position);}

None of the operations need a precondition– Precondition !isDone() only needed when actually

accessing a position on a board– Responsibility may be delegated to the client

Page 23: Iterator behavioural design pattern

1998-09-15 Computer Science, University of

Karlstad23

class ColumnIteratorclass ColumnIterator Inherits BoardIterator Implementation invariant

– current().x() fixed, identifies the column– current().y() is the current row number

Constructor(Board *board) // board != nullColumnIterator(Board *board): BoardIterator(board) {}

Redefined operationvoid next() {current().incY();}

Page 24: Iterator behavioural design pattern

1998-09-15 Computer Science, University of

Karlstad24

RowIteratorRowIterator

Very similar to ColumnIterator– same instance variables as ColumnIterator– iterating over the positions of a row, not those

of a column In this example I show another constructor

– Taking a specific position as an argument– Iterate over a row starting from the position

Page 25: Iterator behavioural design pattern

1998-09-15 Computer Science, University of

Karlstad25

class RowIteratorclass RowIterator

Public constructorsBoardIterator(Board *pb, Point start) {

_current = start; _pBoard = pb;}...RowIterator(Board *pb, Point start): BoardIterator(pb, start) {}

Redefined access function– void next() {current().incX();}