13-1 computing fundamentals with c++ object-oriented programming and design, 2nd edition rick mercer...
TRANSCRIPT
13-1
Computing Fundamentals with C++Computing Fundamentals with C++Object-Oriented Programming and Design, 2nd EditionObject-Oriented Programming and Design, 2nd Edition
Rick MercerRick Mercer
Franklin, Beedle & Associates, 1999Franklin, Beedle & Associates, 1999
ISBN 1-887902-36-8ISBN 1-887902-36-8
Presentation Copyright 1999, Franklin, Beedle & Associates Presentation Copyright 1999, Franklin, Beedle & Associates Students who purchase and instructors who adopt Students who purchase and instructors who adopt Computing Fundamentals with C++, Computing Fundamentals with C++, Object-Oriented Programming and Design Object-Oriented Programming and Design by Rick Mercer are welcome to use this by Rick Mercer are welcome to use this
presentation as long as this copyright notice remains intact.presentation as long as this copyright notice remains intact.
13-2Chapter 13: Object-Oriented Software Chapter 13: Object-Oriented Software Development Development Design and ImplementationDesign and Implementation
Chapter GoalsChapter Goals— See how the analysis deliverable (CRH cards) helps See how the analysis deliverable (CRH cards) helps
programmers design class definitionsprogrammers design class definitions— Implement action responsibilities as public member Implement action responsibilities as public member
functionsfunctions— Implement knowledge responsibilities as private data Implement knowledge responsibilities as private data
membersmembers— Add constructors to initialize the data members.Add constructors to initialize the data members.— Perform unit testingPerform unit testing— Perform system testingPerform system testing
13-313.1 Designing Class 13.1 Designing Class InterfacesInterfaces
The analysis phase helps understand The analysis phase helps understand whatwhat the the system doessystem does
Design concentrates on the Design concentrates on the howhow Next up: designing C++ class definitionsNext up: designing C++ class definitions
— a class encapsulates a class encapsulates • action responsibilities (what an instance should be able action responsibilities (what an instance should be able
to do) as member functions to do) as member functions
• knowledge responsibilities (what each instance should knowledge responsibilities (what each instance should know) as data membersknow) as data members
13-4 Analysis / DesignAnalysis / Design
Analysis
Implementation
Design
Some software is developed using the waterfall Some software is developed using the waterfall model strategy model strategy — Finish one phase before going onto the nextFinish one phase before going onto the next
Problem: harder to go back UP to earlier phaseProblem: harder to go back UP to earlier phase
13-5 Iterative ApproachIterative Approach
Object-Oriented design involves an iterative Object-Oriented design involves an iterative approach that keeps things flexibleapproach that keeps things flexible— more flexible strategy allows more flexible strategy allows
• analysis questions during design analysis questions during design what did you want?what did you want?
• modification of design during implementationmodification of design during implementation
• revisit problem specification while implementingrevisit problem specification while implementing– we just found out that it would nice if .... we just found out that it would nice if ....
— There are no clean rigid walls between analysis, There are no clean rigid walls between analysis, design, and implementationdesign, and implementation
13-6 Can move to any phaseCan move to any phase
Jukebox design had 10 classesJukebox design had 10 classes— The design could change to 8 or 12 classes The design could change to 8 or 12 classes
during design or during implementationduring design or during implementation— The programmers can uncover issues that were The programmers can uncover issues that were
not previously realizednot previously realized— The customer may change her or his mindThe customer may change her or his mind— Implementation may be easier and the product Implementation may be easier and the product
better if we could just change this part of the better if we could just change this part of the specification -- the customer could agree!specification -- the customer could agree!
13-7From CRH Cards to Class From CRH Cards to Class DefinitionsDefinitions
The CRH cards help the team design class The CRH cards help the team design class definitions definitions behavior and knowledgebehavior and knowledge
At this point, the team will At this point, the team will — Specify member functions including parameters and Specify member functions including parameters and
return types for the class member function headingsreturn types for the class member function headings— Determine the knowledge responsibilities (data memb-Determine the knowledge responsibilities (data memb-
ers) required to implement the action responsibilitiesers) required to implement the action responsibilities— Add constructors (or other initialization routines)Add constructors (or other initialization routines)— Implement constructors to initialize data membersImplement constructors to initialize data members— Implement the member functionsImplement the member functions
13-8 Specify Member FunctionsSpecify Member Functions
Write part of the class and add the major Write part of the class and add the major responsibilities responsibilities get and put studentsget and put students
class studentCollection { class studentCollection { // first draft// first draft public:public: ?????? getStudent( getStudent(??????);); private:private: // TBA: knows all students// TBA: knows all students };};
13-9 Second DraftSecond Draft
Add appropriate return types and parameters Add appropriate return types and parameters to the class definitionto the class definition
class studentCollection { class studentCollection { // second draft// second draft public:public: student getStudent(string ID);student getStudent(string ID); // return student associated with ID// return student associated with ID private:private: // TBA: knows all students// TBA: knows all students };};
13-10Add a private operation and Add a private operation and some data member(s) some data member(s) no constructor yetno constructor yet
class studentCollection { class studentCollection { third draftthird draftpublic:public: student getStudent(student ID);student getStudent(student ID); // return student associated with ID// return student associated with ID
void addStudent(student newStudent);void addStudent(student newStudent); // should this be private???? Maybe.// should this be private???? Maybe.private:private: // store all students// store all students vector <student> my_data;vector <student> my_data;};};
13-11Need Need student student nownow
Implement student before declaring a vector of Implement student before declaring a vector of themthem
class student { class student { // first draft// first draft public:public: bool canSelect(track currentSelection);bool canSelect(track currentSelection); // Returns true if student has credit// Returns true if student has credit // and has played less than 2 tracks// and has played less than 2 tracks private:private: // TBA// TBA };};
13-12 StudentStudent
Determine return type (bool) and parameter Determine return type (bool) and parameter of canSelect of canSelect needs playtime so pass trackneeds playtime so pass track
Add one data memberAdd one data member class student { class student { // first draft// first draft public:public: bool canSelect(track currentSelection);bool canSelect(track currentSelection); // Returns true if student has credit// Returns true if student has credit // and has played less than 2 tracks// and has played less than 2 tracks private:private: // data members TBA// data members TBA };};
13-13 Change Class StudentChange Class Student
Student is used too muchStudent is used too much— The author should have used the more meaningful The author should have used the more meaningful
name ofname of• jukeboxAccountjukeboxAccount
• jukeBoxAccountCollectionjukeBoxAccountCollection
Implementing Student and studentCollection is Implementing Student and studentCollection is left as an exerciseleft as an exercise— but please use the namesbut please use the names
• jukeBoxAccount and jukeBoxAccountCollectionjukeBoxAccount and jukeBoxAccountCollection
13-14Implementing the iterator Implementing the iterator patternpattern
During design and implementation, the During design and implementation, the programmer notices this action responsibility:programmer notices this action responsibility:— Allow someonAllow someonee to look at individual CDs or tracks to look at individual CDs or tracks
There is a design pattern for thisThere is a design pattern for this— The iterator patternThe iterator pattern— Design Patterns: Elements of Reusable Object-Design Patterns: Elements of Reusable Object-
Oriented SoftwareOriented Software [Gamma, Helm, Johnson, [Gamma, Helm, Johnson, Vlissides 95]Vlissides 95]
13-15 The iterator patternThe iterator pattern
IntentIntent— Provide a way to access the elements of an Provide a way to access the elements of an
aggregate object sequentially without exposing the aggregate object sequentially without exposing the underlying representationunderlying representation
MotivationMotivation— A container object--such as CD which has a vector A container object--such as CD which has a vector
of track objects--should give access to its elements of track objects--should give access to its elements without exposing its internal structure without exposing its internal structure
13-16 Need more member functionsNeed more member functions
To implement this pattern, the following To implement this pattern, the following operations must be availableoperations must be available
first()first()next()next()isDone()isDone()
currentItem()currentItem()
The cdCollection definition with iterator pattern The cdCollection definition with iterator pattern is shown in its final form is shown in its final form next slidenext slide
13-17
class cdCollection { class cdCollection { public:public: cdCollection();cdCollection(); void addCD(const CD & nextCD);void addCD(const CD & nextCD); bool removeCD(const CD & aCD);bool removeCD(const CD & aCD); int size() const;int size() const; CD getCD(int cdNumber) const;CD getCD(int cdNumber) const;//--iterator functions://--iterator functions: void first(); void first(); // my_index points to first CD// my_index points to first CD void next(); void next(); // index point to the next CD// index point to the next CD bool isDone() const; bool isDone() const; // is traversal done?// is traversal done? CD currentItem() const; CD currentItem() const; private:private: vector < CD > my_data; vector < CD > my_data; // store the CDs// store the CDs int my_size; int my_size; int my_index;int my_index;};};
13-18 ImplementationImplementation
The class definitions can be written and stored in The class definitions can be written and stored in .h files.h files
They could be compiled separatelyThey could be compiled separatelyThey should have all data members and the They should have all data members and the
constructors to initializeconstructors to initializeAlthough this is design, it is also implementation Although this is design, it is also implementation
need the class definitionneed the class definition
Let's implement a few classes in .cpp filesLet's implement a few classes in .cpp files
13-19 track, CD, cdCollectiontrack, CD, cdCollection
During implementationDuring implementation— choose the data to store the knowledge choose the data to store the knowledge
responsibilitiesresponsibilities• could be int, string, double, vector, cardReader,…could be int, string, double, vector, cardReader,…
— select constructors or other proper initialization select constructors or other proper initialization membersmembers
— refine class definitionsrefine class definitions— add action responsibilitiesadd action responsibilities
Team decides to do Team decides to do tracktrack, , CDCD, and , and cdCollectioncdCollection
13-20 track track class definitionclass definition
class track { class track { // no constructor yet// no constructor yetpublic:public: seconds playTime();seconds playTime(); // returns seconds required to play// returns seconds required to play int trackNumber();int trackNumber(); // this track's location on the CD// this track's location on the CD int cdNumber();int cdNumber(); // the tray location in the CD player// the tray location in the CD playerprivate:private: seconds my_playTime;seconds my_playTime; int my_trackNumber;int my_trackNumber; int my_cdNumber;int my_cdNumber;};};
13-21
// file name: track.h// file name: track.h// Final version of track's class definition// Final version of track's class definitionclass track { class track { public:public: track(); track(); // default constructor// default constructor track(string initTitle, seconds initPlayTime, track(string initTitle, seconds initPlayTime, int initCdNumber, int initTrackNumber);int initCdNumber, int initTrackNumber); string title() const;string title() const; seconds playTime() const;seconds playTime() const; int cdNumber() const;int cdNumber() const; int trackNumber() const;int trackNumber() const;private:private: string my_title;string my_title; seconds my_playTime;seconds my_playTime; int my_cdNumber;int my_cdNumber; int my_trackNumber;int my_trackNumber;};};
track track class with constructorsclass with constructors
13-22 Implement Member FunctionsImplement Member Functions
The next few slides show the member function The next few slides show the member function implementationsimplementations
This is followed by a test driver for trackThis is followed by a test driver for trackEach class must be tested at least byEach class must be tested at least by
— calling every member function oncecalling every member function once— construct a vector of the objects (if they are to go construct a vector of the objects (if they are to go
into a container that is)into a container that is)
13-23
// file name: track.cpp// file name: track.cpp#include "track.h" // for track's class def.#include "track.h" // for track's class def.
// default constructor: track t1;// default constructor: track t1;track::track()track::track(){ // Initialize a default track{ // Initialize a default track my_title = "?title?";my_title = "?title?"; my_playTime = 0;my_playTime = 0; my_cdNumber = 0;my_cdNumber = 0; my_trackNumber = 0;my_trackNumber = 0;}}
// constructor: track t2( "Dog", 255, 5, 2 );// constructor: track t2( "Dog", 255, 5, 2 );track::track( string initTitle, track::track( string initTitle, seconds initPlayTime, seconds initPlayTime, int initCdNumber, int initCdNumber, int initTrackNumber )int initTrackNumber ){ { // Initialize a track object with arguments// Initialize a track object with arguments my_title = initTitle;my_title = initTitle; my_playTime = initPlayTime;my_playTime = initPlayTime; my_trackNumber = initTrackNumber;my_trackNumber = initTrackNumber; my_cdNumber = initCdNumber;my_cdNumber = initCdNumber;}}
13-24// file name: track.cpp continued// file name: track.cpp continued// Accessing member functions// Accessing member functionsseconds track::playTime() constseconds track::playTime() const{{ return my_playTime;return my_playTime;}} int track::trackNumber() constint track::trackNumber() const{{ return my_trackNumber;return my_trackNumber;}} int track::cdNumber() constint track::cdNumber() const{{ return my_cdNumber;return my_cdNumber;}}
string track::title() conststring track::title() const{{ return my_title;return my_title;}}
13-25// This test driver call all member functions// This test driver call all member functions#include <iostream>#include <iostream>using namespace std;using namespace std;#include "track" #include "track" int main()int main(){ { // test drive track// test drive track track t1;track t1; track t2("I'm the Cat", 3*60+55, 5, 1);track t2("I'm the Cat", 3*60+55, 5, 1); cout << t2.title() << endl;cout << t2.title() << endl; cout << t2.playTime() << " or " cout << t2.playTime() << " or " << t2.playTime() / 60 << " minutes and " << t2.playTime() / 60 << " minutes and " << t2.playTime() % 60 << " seconds"<<endl;<< t2.playTime() % 60 << " seconds"<<endl; cout << "track# " << t2.trackNumber() << endl;cout << "track# " << t2.trackNumber() << endl; cout << " CD# " << t2.cdNumber() << endl;cout << " CD# " << t2.cdNumber() << endl;}}
Output:Output:
Test driver calls all member functionsTest driver calls all member functions
I'm the CatI'm the Cat235 or 3 minutes and 55 235 or 3 minutes and 55 secondssecondstrack #1track #1 CD #5CD #5 Demo t_track.cpp
13-26 A first cut at A first cut at CDCD
class CD { class CD { // first draft// first draftpublic:public: string artist();string artist(); string title();string title();private:private: string my_artist;string my_artist; string my_title;string my_title; vector <track> my_data; vector <track> my_data; // many tracks// many tracks int my_size; int my_size; // # of tracks// # of tracks};};
13-27 class CDclass CD final designfinal design
class CD {class CD {public:public://--constructors//--constructors // default constructor allows vector of tracks// default constructor allows vector of tracks CD(); CD();
// initialize a CD with 0 tracks// initialize a CD with 0 tracks CD( string initArtist, CD( string initArtist, string initTitle, string initTitle, int initCdNumber);int initCdNumber);
//--modifier//--modifier void addTrack(const track & nextTrack);void addTrack(const track & nextTrack); // add a new track--missed this during design// add a new track--missed this during design
13-28
//--accessors//--accessors string artist() const;string artist() const; // return this CD's artist// return this CD's artist
string title() const;string title() const; // return the title of this CD// return the title of this CD
int cdNumber() const;int cdNumber() const; // return the physical location in CD player// return the physical location in CD player
track getTrack(int trackNum) const;track getTrack(int trackNum) const; // Given the trackNum, return the track object// Given the trackNum, return the track object
int size() const;int size() const; // return the number of tracks on this CD// return the number of tracks on this CD
//--iterator functions//--iterator functions void first(); void first(); void next(); void next(); bool isDone() const; bool isDone() const; track currentItem() const; track currentItem() const;
13-29
// Data members: shouldn't matter to user// Data members: shouldn't matter to user// But they sure do matter to the implementers// But they sure do matter to the implementers
private:private: string my_artist;string my_artist; string my_title;string my_title; vector < track > my_data; vector < track > my_data; int my_size; int my_size; int my_index; int my_index; int my_cdNumber;int my_cdNumber;};};
13-30
#include <iostream>#include <iostream>using namespace std;using namespace std;#include "cd"#include "cd"
void show(const track & t2);void show(const track & t2);// show the data stored on one track// show the data stored on one track
int main()int main(){ { // test drive CD// test drive CD CD aCD("Browne, Jackson", "Facing East");CD aCD("Browne, Jackson", "Facing East"); aCD.addTrack(track( "Looking East", 296, 5, 1));aCD.addTrack(track( "Looking East", 296, 5, 1)); // add 9 more tracks to CD// add 9 more tracks to CD // … 9 lines of code deleted// … 9 lines of code deleted
Test Drive CD Test Drive CD
13-31 Show all tracks on the CDShow all tracks on the CD
cout << aCD.artist() << " " << aCD.title() << endl;cout << aCD.artist() << " " << aCD.title() << endl;
// Iterate over all tracks on the CD// Iterate over all tracks on the CD track aTrack;track aTrack;
aCD.first(); while( ! aCD.isDone() ) { aTrack = aCD.currentItem(); show(aTrack); aCD.next(); } return 0;return 0;}}
Visit all Visit all
objects objects
with the with the
iterator iterator
methodsmethods
13-32 A Free Function to help testA Free Function to help test
void show(const track & aTrack)void show(const track & aTrack){{ cout.width(2);cout.width(2); cout << aTrack.trackNumber();cout << aTrack.trackNumber(); cout.width(3);cout.width(3); cout << aTrack.cdNumber() << " ";cout << aTrack.cdNumber() << " "; cout << aTrack.title()cout << aTrack.title() << " " << (aTrack.playTime() / 60) << " " << (aTrack.playTime() / 60) << ":" << (aTrack.playTime() % 60) << endl;<< ":" << (aTrack.playTime() % 60) << endl;}}
Output from first track:Output from first track: 1 5 Looking East 4:561 5 Looking East 4:56
Demo t_cd.cpp
13-33ConsiderConsidercdCollectioncdCollection
The cdCollection should be able to remove The cdCollection should be able to remove and add CDs and add CDs this uses a vector to store CD objectsthis uses a vector to store CD objects
class cdCollection { class cdCollection { // third draft// third draft public: public: void addCD(const CD & aCD);void addCD(const CD & aCD); // add a CD to the collection if possible // add a CD to the collection if possible bool removeCD(const CD & aCD);bool removeCD(const CD & aCD); // remove CD if possible. // remove CD if possible. private:private: vector < CD > my_data;vector < CD > my_data; int my_size;int my_size; }; };
class: cdCollection
Responsibilities Collaborators
Know all CDs vector or bag?
Allow someone to look at all CDs CD addCD removeCD
Demo t_cdcollection.cpp
13-34Summary of implementing Summary of implementing individual classesindividual classes
Each class can be designed like thisEach class can be designed like this— first as a CRH cardfirst as a CRH card— then as a class definition with action responsibilities then as a class definition with action responsibilities
listed as member functionlisted as member function— then refine return types and parametersthen refine return types and parameters— add data membersadd data members— add constructorsadd constructors— implement member functionsimplement member functions— test the class test the class
• at a minimum, call every methodat a minimum, call every method
13-35 13.3 System Testing13.3 System Testing
Need to put everything together and test the Need to put everything together and test the entire systementire system
In this case, consider a jukebox class that In this case, consider a jukebox class that contains the major classescontains the major classes
Then jukebox can coordinate the activities Then jukebox can coordinate the activities between those objectsbetween those objects
First consider the main functionFirst consider the main function— see next slidesee next slide
13-36 What int main might look likeWhat int main might look like
Jukebox will start and stop thingsJukebox will start and stop things
#include "jukebox" #include "jukebox" // for class jukebox // for class jukebox
int main() int main() // first draft// first draft { { // One possibility--still undecided// One possibility--still undecided jukeBox theJukeBox; jukeBox theJukeBox;
while(theJukeBox.isRunning()) while(theJukeBox.isRunning()) {{ theJukeBox.processOneUser();theJukeBox.processOneUser(); }} return 0;return 0; }}
Demo runjuke.cpp
13-37 first cut at first cut at jukeBoxjukeBox
Jukebox Jukebox contains contains the major objectsthe major objects
class jukeBox { class jukeBox { // first draft// first draft public:public: void processOneUser();void processOneUser(); // Do what's necessary to process one user// Do what's necessary to process one user
bool isRunning();bool isRunning(); // true until jukeBox detects it's time to quit// true until jukeBox detects it's time to quit
private:private: cardReader my_cardReader;cardReader my_cardReader; cdCollection my_cdCollection;cdCollection my_cdCollection; studentCollection my_studentCollection;studentCollection my_studentCollection; userInterface my_userInterface;userInterface my_userInterface; };};
13-38 Assessing the DesignAssessing the Design
Some examples of good designSome examples of good design— A class that contains objects of another class A class that contains objects of another class
should be sending messages to themshould be sending messages to them• Jukebox does this. If it didn't, you have extraneous Jukebox does this. If it didn't, you have extraneous
objects in the classobjects in the class— CDCollection does not know who contains itCDCollection does not know who contains it
• my_CdCollection does not send messages to Jukebox my_CdCollection does not send messages to Jukebox -- CDCollection could be reused-- CDCollection could be reused
13-39 Good Design?Good Design?
Other examples of good designOther examples of good design— The contained classes don't use each other The contained classes don't use each other — System intelligence is distributed well enough that System intelligence is distributed well enough that
Jukebox does very littleJukebox does very little• consider the ease with which Jukebox gets the user consider the ease with which Jukebox gets the user
desired selection based on the contents of the desired selection based on the contents of the cdCollectioncdCollection
my_currentSelection =my_currentSelection = my_trackSelector.getTrack(my_cdCollection)my_trackSelector.getTrack(my_cdCollection)