Design Patterns (Composite, Iterator)

Similar documents
Design Patterns (Composite)

Design Patterns (Facade, Composite)

Design Patterns (Iterator)

Today's Agenda. References. Open Closed Principle. CS 247: Software Engineering Principles. Object-Oriented Design Principles

Last Lecture. Lecture 17: Design Patterns (part 2) Kenneth M. Anderson Object-Oriented Analysis and Design CSCI 4448/ Spring Semester, 2005

CSCI 253. Overview. The Elements of a Design Pattern. George Blankenship 1. Object Oriented Design: Iterator Pattern George Blankenship

Software Eningeering. Lecture 9 Design Patterns 2

Design Patterns Lecture 2

CS 246: Software Abstraction and Specification. Lecture 8. Object Composition

C++ (Non for C Programmer) (BT307) 40 Hours

SDC Design patterns GoF

» Access elements of a container sequentially without exposing the underlying representation

Think of drawing/diagramming editors. ECE450 Software Engineering II. The problem. The Composite pattern

Design Patterns. "Gang of Four"* Design Patterns. "Gang of Four" Design Patterns. Design Pattern. CS 247: Software Engineering Principles

CS 247: Software Engineering Principles. Design Patterns

CS 520 Theory and Practice of Software Engineering Fall 2017

CS250 Intro to CS II. Spring CS250 - Intro to CS II 1

20. Inheritance and Polymorphism

Object-Oriented Oriented Programming

FINAL TERM EXAMINATION SPRING 2010 CS304- OBJECT ORIENTED PROGRAMMING

COSC 3351 Software Design. Design Patterns Structural Patterns (I)

CS560. Lecture: Design Patterns II Includes slides by E. Gamma et al., 1995

Design Pattern and Software Architecture: IV. Design Pattern

Object-Oriented Languages and Object-Oriented Design. Ghezzi&Jazayeri: OO Languages 1

An Introduction to Patterns

CS 520 Theory and Practice of Software Engineering Fall 2018

A Case Study of Gang of Four (GoF) Patterns : Part 7

ECE 449 OOP and Computer Simulation Lecture 11 Design Patterns

CS 320 Introduction to Software Engineering Spring March 06, 2017

Design Patterns. Lecture 10: OOP, autumn 2003

What are patterns? Design Patterns. Design patterns. Creational patterns. The factory pattern. Factory pattern structure. Lecture 10: OOP, autumn 2003

Short Notes of CS201

Design Patterns Reid Holmes

CS 520 Theory and Practice of Software Engineering Fall 2018

Spring 2003 Instructor: Dr. Shahadat Hossain. Administrative Matters Course Information Introduction to Programming Techniques

CS201 - Introduction to Programming Glossary By

18. Inheritance and Polymorphism

Object Oriented Programming

Containers: Stack. Jordi Cortadella and Jordi Petit Department of Computer Science

Containers: Stack. The Stack ADT. The Stack ADT. The Stack ADT

Design Patterns. Manuel Mastrofini. Systems Engineering and Web Services. University of Rome Tor Vergata June 2011

CS304 Object Oriented Programming Final Term

The Strategy Pattern Design Principle: Design Principle: Design Principle:

Produced by. Design Patterns. MSc in Communications Software. Eamonn de Leastar

What is a Pattern? Lecture 40: Design Patterns. Elements of Design Patterns. What are design patterns?

Design Patterns. Definition of a Design Pattern

Chapter 20: Binary Trees

Linear Structures. Linear Structure. Implementations. Array details. List details. Operations 4/18/2013

Design Patterns. (and anti-patterns)

Design Pattern. CMPSC 487 Lecture 10 Topics: Design Patterns: Elements of Reusable Object-Oriented Software (Gamma, et al.)

Design patterns. Jef De Smedt Beta VZW

What are the characteristics of Object Oriented programming language?

Linear Structures. Linear Structure. Implementations. Array details. List details. Operations 2/10/2013

CPSC 310: Sample Final Exam Study Questions 2014S1 (These are in addition to the Study Questions listed at the end of some lectures)

C++ Modern and Lucid C++ for Professional Programmers

Inheritance. OOP components. Another Example. Is a Vs Has a. Virtual Destructor rule. Virtual Functions 4/13/2017

CSCI-1200 Computer Science II Fall 2006 Lecture 23 C++ Inheritance and Polymorphism

Software Construction

CS246 Software Abstraction and Specification Final Examination

Principles of Software Design. Software Engineering Alessio Gambi Saarland University

CSE 70 Final Exam Fall 2009

CS304 Object Oriented Programming

ECE 3574: Dynamic Polymorphism using Inheritance

CS250 Final Review Questions

Zhifu Pei CSCI5448 Spring 2011 Prof. Kenneth M. Anderson

! Tree: set of nodes and directed edges. ! Parent: source node of directed edge. ! Child: terminal node of directed edge

Last Lecture. Lecture 26: Design Patterns (part 2) State. Goals of Lecture. Design Patterns

Refresher: Interface Specifications. ADT Documentation. Set Represented as an Array. Representation Invariant, Abstraction Function

Type Inference Systems. Type Judgments. Deriving a Type Judgment. Deriving a Judgment. Hypothetical Type Judgments CS412/CS413

2.1 Design Patterns and Architecture (continued)

Representation Invariant, Abstraction Function

22. Subtyping, Inheritance and Polymorphism

2.1 Design Patterns and Architecture (continued)

CSCI-1200 Data Structures Fall 2017 Lecture 25 C++ Inheritance and Polymorphism

CSE 431S Type Checking. Washington University Spring 2013

Produced by. Design Patterns. MSc in Communications Software. Eamonn de Leastar

CprE 288 Introduction to Embedded Systems Exam 1 Review. 1

The Composite Design Pattern

Lecture 3. COMP1006/1406 (the Java course) Summer M. Jason Hinek Carleton University

COMP6771 Advanced C++ Programming

Computer Science II CSci 1200 Lecture 24 C++ Inheritance and Polymorphism

EPL 603 TOPICS IN SOFTWARE ENGINEERING. Lab 6: Design Patterns

Composite Pattern. IV.4 Structural Pattern

1 Software Architecture

CSCD01 Engineering Large Software Systems. Design Patterns. Joe Bettridge. Winter With thanks to Anya Tafliovich

An Introduction to Object Orientation

Details of Class Definition

! Tree: set of nodes and directed edges. ! Parent: source node of directed edge. ! Child: terminal node of directed edge

Maintainable Software. Software Engineering Andreas Zeller, Saarland University

Instantiation of Template class

Review Questions for Final Exam

STRICT_VARIANT. A simpler variant in C++ Chris Beck

LECTURE 18. Control Flow

class Polynomial { public: Polynomial(const string& N = "no name", const vector<int>& C = vector<int>());... };

Binary Tree. Binary tree terminology. Binary tree terminology Definition and Applications of Binary Trees

COURSE 2 DESIGN PATTERNS

Lecture 7: Type Systems and Symbol Tables. CS 540 George Mason University

Binary Trees. Height 1

OBJECT ORIENTED PROGRAMMING. Ms. Ajeta Nandal C.R.Polytechnic,Rohtak

Object-Oriented Programming

Transcription:

CS 246: Software Abstraction and Specification Lecture 17 Design Patterns (Composite, Iterator) Reading: Head First Design Patterns U Waterloo CS246se (Spring 2011) p.1/30

Today's Agenda Design patterns: codified solutions that put design principles into practice, to improve the modularity of our code. OO Basics Favour Composition over Inheritance Model-View-Controller (MVC) Separation of Concerns Single Responsibility Principle Composite Loose Coupling Principle of Least Knowledge (Law Iterator of Demeter) Information Hiding Avoid duplicate code Encapsulate what is likely to change OO Principles Strategy Program to an Interface, not an Factory Implementation Method Liskov Substitutability PrincipleObserver Design Patterns Template Method U Waterloo CS246se (Spring 2011) p.2/30

Review: Object Composition A compound object represents a composition of heterogeneous, possibly recursive, component objects Law of Demeter: client code interacts with compound object Document 1 * 0..1 Section * Transcript 1 * Term Record 1 1 * Page 1..* Course Enrollment * Player * 0..1 Team * subteam 1 Course number description credits U Waterloo CS246se (Spring 2011) p.3/30

Composite Pattern Idea The Composite Pattern takes a different approach: gives the client access to all members in a compound object via a uniform interface. Client Code TeamMember * Player Team Client Code 2 Expr value() print() BinaryExpr Variable name value Plus Minus Multiply Divide U Waterloo CS246se (Spring 2011) p.4/30

Composite Pattern Problem: composite object consists of several heterogenous parts Client code is complicated by knowledge of object structure Client must change if data structure changes Solution: create a uniform interface for the object's components Interface advertises all operations that components offer Client deals only with the new uniform interface Client Code Component Operation add(component) Remove(Component) GetChild(int) * part Leaf Operation Composite Operation add(component) Remove(Component) GetChild(int) U Waterloo CS246se (Spring 2011) p.5/30

Example: Expressions 2 BinaryExpr left() : Expr right() : Expr print() Expression value() print() Variable name value name() value() print() Expressions: a+b a*b+c-d a Plus Minus Multiply Divide U Waterloo CS246se (Spring 2011) p.6/30

Implementing the Component Interface Because the interface of the Component Class is to be uniform, it comprises the union of all component classes. class Expression { public: // leaf-only operations virtual string name() const; // composite-only operations virtual const Expression* left() const; virtual const Expression* right() const; //shared operations virtual int value() const; virtual void print() const; private: Expression(); ; U Waterloo CS246se (Spring 2011) p.7/30

Uniformity vs. Safety Whether to include component-specific operations in the component interface involves a trade-off between uniformity - preserving the illusion that component objects can be treated the same way - promoted by the Composite Pattern safety - avoiding cases where the client attempts to do something meaningless, like adding components to Leaf objects - promoted by Liskov Substitutability Principle U Waterloo CS246se (Spring 2011) p.8/30

Implementing the Component Interface What default implementation makes sense? class Expression { public: // leaf-only operations virtual string name() const {return ""; // composite-only operations virtual const Expression* left() const {return 0; virtual const Expression* right() const {return 0; //shared operations virtual int value() const {return 0; virtual void print() const { private: Expression(); ; U Waterloo CS246se (Spring 2011) p.9/30

Implementing the Leaf Class The leaf classes override the behaviour of leaf-object operations. class Variable : public Expression { public: Variable (std::string, int); // redefine leaf-only operations virtual std::string name() const {return name_; // inherit default behaviour of composite-only operations // redefine shared operations virtual int value() const {return value_; virtual void print() const {std::cout << name(); private: std::string name_; int value_; ; U Waterloo CS246se (Spring 2011) p.10/30

Implementing the Composite The composite classes override composite-object operations. class BinaryExpr : public Expression { public: ~BinaryExpr(); // inherit default behaviour of leaf-only operations // redefine composite operations virtual Expression* left() const {return leftchild_; virtual Expression* right() const {return rightchild_; private: Expression* leftchild_; Expression* rightchild_; protected: BinaryExpr(Expression* a, Expression *b); ; U Waterloo CS246se (Spring 2011) p.11/30

Implementing the Composite The (concrete) composite classes specialize the composite methods that are operator specific. class Plus : public BinaryExpr { public: Plus(Expression*, Expression*); // redefine shared operations int value() const; void print() const; ; int Plus::value() const { return left()->value() + right()->value(); void Plus::print() const { left()->print(); std::cout << " + "; right()->print(); U Waterloo CS246se (Spring 2011) p.12/30

Another Example 0..1 Developer * Project Team * subteam TeamMember name : string name() : string salary() print() add(teammember) remove(teammember) getmember(int) * member Developer salary: float salary() print() ProjectTeam print() add(teammember) remove(teammember) getmember(int) U Waterloo CS246se (Spring 2011) p.13/30

Component Interface class TeamMember { public: // leaf-only operations virtual int salary() const; // component-only operations virtual void add(teammember*); virtual void remove(teammember*); virtual TeamMember* getmember(int) const; // shared operations std::string name() const; virtual void print() const; protected: TeamMember( std::string name ); private: std::string name_; ; U Waterloo CS246se (Spring 2011) p.14/30

Composite Pattern 2 Expression value() print() Client BinaryExpr left() : Expr right() : Expr print() Variable name value name() value() print() Plus Minus Multiply Divide Consequences: + Client deals only with the new uniform interface + New leafs and composite types are easy to add New operations are harder to add (Visitor Pattern) How can client code iterate through a composite object without knowing the composite's structure? U Waterloo CS246se (Spring 2011) p.15/30

Iterator Pattern Goals: (1) To encapsulate the strategy for iterating through a composite (so that it can be changed, at run-time). (2) Allow the client to iterate through a composite without exposing the composite's representation. Collection createiterator() size() getelem(int) Client Iterator first() hasnext() next() ConcreteCollection createiterator() size() getelem(int) <<create>> ConcreteIterator first() hasnext() next() U Waterloo CS246se (Spring 2011) p.16/30

Collection createiterator() size() getelem(int) Department createiterator() size() getelem(int) Operation() * Prof Simple Iteration <<create>> Operation to retrieve specific element Client Iterator first() hasnext() next() DepartmentIterator first() hasnext() next() Operations to retrieve all elements, systematically // client code Department* dept; DepartmentIterator* iter = dept->createiterator(); iter->first(); while ( iter->hasnext() ) { Prof* p = iter->next(); // process p U Waterloo CS246se (Spring 2011) p.17/30

Department Composite class is augmented with operations to support the Iterator Pattern. class Department { public: virtual int size(); virtual Prof* getelem(int); virtual Iterator* createiterator(); // other operations private: std::vector<prof*> dept_; ; Iterator* Department::createIterator() { return new DepartmentIterator(this); U Waterloo CS246se (Spring 2011) p.18/30

Department Iterator class DepartmentIterator { // retrieves elements in vector order private: Department* dept_; int cursor_; public: DepartmentIterator(Department* dept) : dept_(dept), cursor_(0) { virtual void first() { cursor_ = 0; virtual bool hasnext(); virtual Prof* next(); ; bool DepartmentIterator::hasNext() { return (cursor_ < dept_->size()); Prof* DepartmentIterator::next() { Prof* result = (dept_->getelem(cursor_)); cursor_ += 1; return result; U Waterloo CS246se (Spring 2011) p.19/30

Iteration over a Composite Object The more interesting case is when the aggregate is a composite object, in which case we need to construct an Iterator that understands and navigates the composite. Company Division A Division B Tom Tiger Team Special Ops Team Alice Ajit Sandy Ali U Waterloo CS246se (Spring 2011) p.20/30

Composite Iteration collection TeamMember name() salary() add (TeamMember) remove (TeamMember) createiterator() size() getchild(int) * Client Iterator first() hasnext() next() iterator Developer salary() createiterator() Team add (TeamMember) remove (TeamMember) createiterator() size() getchild(int) <<create>> <<create>> TeamIterator TeamIterator(Team) first() hasnext() next() DevIterator DevIterator(Developer) first() hasnext() next() U Waterloo CS246se (Spring 2011) p.21/30

Client Code Iterate through all members in the composite. TeamMember* employees;... Iterator* iter = employees->createiterator(); iter->first(); while ( iter->hasnext() ) { TeamMember* m = iter->next(); // process member m Different iterator can iterate through all leaf objects in the composite. TeamMember* employees;... Iterator* iter = employees->createdevonlyiterator(); iter->first(); while ( iter->hasnext() ) { TeamMember* m = iter->next(); RequestPayCheck(m->name(), m->salary()); U Waterloo CS246se (Spring 2011) p.22/30

Create Iterator Each concrete subclass in the composite knows how to create its own corresponding Iterator. Iterator* Developer::createIterator() { return new DevIterator(this); Iterator* Team::createIterator() { return new TeamIterator(this); U Waterloo CS246se (Spring 2011) p.23/30

Developer Iterator class DevIterator : public Iterator { private: Developer* dev_; Developer* cursor_; public: DevIterator(Developer* dev) : dev_(dev), cursor_(dev) { virtual void first() { cursor_ = dev_; virtual bool hasnext() { return (cursor_!= NULL); virtual TeamMember* next(); ; TeamMember* DevIterator::next() { if ( hasnext() ) { cursor = NULL; return dev_; return NULL; U Waterloo CS246se (Spring 2011) p.24/30

Team Behaviour The Composite objects contribute to iteration with operations to retrieve specific elements. class Team : public TeamMember { private: std::vector<teammember*> members_;... public:... virtual int size() { return members_->size(); virtual TeamMember* getchild(int i) { return members_->at(i); ; U Waterloo CS246se (Spring 2011) p.25/30

Team Iterator The composite iterator needs to iterate over the composite object, including several subobjects. We achieve this by keeping an iterator (cursor) for each collection in composite putting iterators on stack as the collections are encountered class TeamIterator : public Iterator { private: TeamMember* members_; // pointer to composite struct Iter; // < collection, cursor> std::stack<iter*> istack; // stack of iterators public: TeamIterator(TeamMember* m) : members_(m) { first(); virtual void first(); // initialize Iterator stack virtual bool hasnext(); virtual TeamMember* next(); ; U Waterloo CS246se (Spring 2011) p.26/30

TeamIterator::first() Initialize the iterator stack with a cursor for the whole composite. struct TeamIterator::Iter { TeamMember *collect_; int cursor_; // ranges from -1.. collect_->size() Iter(TeamMember *m) : collect_(m), cursor_(-1) { ; void TeamIterator::first() { while (!istack.empty() ) { istack.pop(); istack.push(new Iter(members_)); U Waterloo CS246se (Spring 2011) p.27/30

TeamIterator::next() TeamMember* TeamIterator::next() { // preorder iteration if ( hasnext() ) { // have cursors reached their limit? Iter* top = istack.top(); istack.pop(); // cursor points to member (could be Developer or Team) if (top->cursor_==-1) { top->cursor_ += 1; istack.push(top); // advance cursor to first element return top->collect_;// return member // cursor points to elem within collection member TeamMember *elem = top->collect_->getchild(top->cursor_); top->cursor_ += 1; istack.push(top); // advance cursor to next element istack.push(new Iter(elem)); // push new element on stack return next(); // recurse else return 0; U Waterloo CS246se (Spring 2011) p.28/30

TeamIterator::hasNext() Check if stack contains an iterator that has not retrieved all elements of its respective collection bool TeamIterator::hasNext() { while (!istack.empty() ) { Iter *top = istack.top(); if (top->collect_->size() > top->cursor_) { return true; istack.pop(); delete top; return false; U Waterloo CS246se (Spring 2011) p.29/30

Summary The goal of design patterns is to encapsulate change Composite Pattern: encapsulates the structure of a heterogeneous, possibly recursive data structure Iterator Pattern: encapsulates the iteration of a heterogeneous, possibly recursive data structure U Waterloo CS246se (Spring 2011) p.30/30