Presentation is loading. Please wait.

Presentation is loading. Please wait.

13-1 Computing Fundamentals with C++ Object-Oriented Programming and Design, 2nd Edition Rick Mercer Franklin, Beedle & Associates, 1999 ISBN 1-887902-36-8.

Similar presentations


Presentation on theme: "13-1 Computing Fundamentals with C++ Object-Oriented Programming and Design, 2nd Edition Rick Mercer Franklin, Beedle & Associates, 1999 ISBN 1-887902-36-8."— Presentation transcript:

1 13-1 Computing Fundamentals with C++ Object-Oriented Programming and Design, 2nd Edition Rick Mercer Franklin, Beedle & Associates, 1999 ISBN 1-887902-36-8 Presentation Copyright 1999, Franklin, Beedle & Associates Students who purchase and instructors who adopt Computing Fundamentals with C++, Object-Oriented Programming and Design by Rick Mercer are welcome to use this presentation as long as this copyright notice remains intact.

2 13-2 Chapter 13: Object-Oriented Software Development Design and Implementation  Chapter Goals — See how the analysis deliverable (CRH cards) helps programmers design class definitions — Implement action responsibilities as public member functions — Implement knowledge responsibilities as private data members — Add constructors to initialize the data members. — Perform unit testing — Perform system testing

3 13-3 13.1 Designing Class Interfaces  The analysis phase helps understand what the system does  Design concentrates on the how  Next up: designing C++ class definitions — a class encapsulates action responsibilities (what an instance should be able to do) as member functions action responsibilities (what an instance should be able to do) as member functions knowledge responsibilities (what each instance should know) as data members knowledge responsibilities (what each instance should know) as data members

4 13-4 Analysis / Design Analysis Implementation Design  Some software is developed using the waterfall model strategy — Finish one phase before going onto the next  Problem: harder to go back UP to earlier phase

5 13-5 Iterative Approach  Object-Oriented design involves an iterative approach that keeps things flexible — more flexible strategy allows analysis questions during design what did you want? analysis questions during design what did you want? modification of design during implementation modification of design during implementation revisit problem specification while implementing revisit problem specification while implementing –we just found out that it would nice if.... — There are no clean rigid walls between analysis, design, and implementation

6 13-6 Can move to any phase  Jukebox design had 10 classes — The design could change to 8 or 12 classes during design or during implementation — The programmers can uncover issues that were not previously realized — The customer may change her or his mind — Implementation may be easier and the product better if we could just change this part of the specification -- the customer could agree!

7 13-7 From CRH Cards to Class Definitions  The CRH cards help the team design class definitions behavior and knowledge  At this point, the team will — Specify member functions including parameters and return types for the class member function headings — Determine the knowledge responsibilities (data memb- ers) required to implement the action responsibilities — Add constructors (or other initialization routines) — Implement constructors to initialize data members — Implement the member functions

8 13-8 Specify Member Functions  Write part of the class and add the major responsibilities get and put students class studentCollection { // first draft class studentCollection { // first draft public: public: ??? getStudent(???); ??? getStudent(???); private: private: // TBA: knows all students // TBA: knows all students }; };

9 13-9 Second Draft  Add appropriate return types and parameters to the class definition class studentCollection { // second draft class studentCollection { // 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 }; };

10 13-10 Add a private operation and some data member(s) no constructor yet class studentCollection { third draft 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: // store all students // store all students vector my_data; vector my_data;};

11 13-11 Need student now  Implement student before declaring a vector of them class student { // first draft class student { // 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 }; };

12 13-12 Student  Determine return type (bool) and parameter of canSelect needs playtime so pass track  Add one data member class student { // first draft class student { // 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-13 Change Class Student  Student is used too much — The author should have used the more meaningful name of jukeboxAccount jukeboxAccount jukeBoxAccountCollection jukeBoxAccountCollection  Implementing Student and studentCollection is left as an exercise — but please use the names jukeBoxAccount and jukeBoxAccountCollection jukeBoxAccount and jukeBoxAccountCollection

14 13-14 Implementing the iterator pattern  During design and implementation, the programmer notices this action responsibility: — Allow someone to look at individual CDs or tracks  There is a design pattern for this — The iterator pattern — Design Patterns: Elements of Reusable Object- Oriented Software [Gamma, Helm, Johnson, Vlissides 95]

15 13-15 The iterator pattern  Intent — Provide a way to access the elements of an aggregate object sequentially without exposing the underlying representation  Motivation — A container object--such as CD which has a vector of track objects--should give access to its elements without exposing its internal structure

16 13-16 Need more member functions  To implement this pattern, the following operations must be available first()next()isDone() currentItem() currentItem()  The cdCollection definition with iterator pattern is shown in its final form next slide

17 13-17 class cdCollection { 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: void first(); // my_index points to first CD void first(); // my_index points to first CD void next(); // index point to the next CD void next(); // index point to the next CD bool isDone() const; // is traversal done? bool isDone() const; // is traversal done? CD currentItem() const; CD currentItem() const;private: vector my_data; // store the CDs vector my_data; // store the CDs int my_size; int my_size; int my_index; int my_index;};

18 13-18 Implementation  The class definitions can be written and stored in.h files  They could be compiled separately  They should have all data members and the constructors to initialize  Although this is design, it is also implementation need the class definition  Let's implement a few classes in.cpp files

19 13-19 track, CD, cdCollection  During implementation — choose the data to store the knowledge responsibilities could be int, string, double, vector, cardReader,… could be int, string, double, vector, cardReader,… — select constructors or other proper initialization members — refine class definitions — add action responsibilities  Team decides to do track, CD, and cdCollection

20 13-20 track class definition class track { // no constructor yet 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: seconds my_playTime; seconds my_playTime; int my_trackNumber; int my_trackNumber; int my_cdNumber; int my_cdNumber;};

21 13-21 // file name: track.h // Final version of track's class definition class track { public: track(); // default constructor track(); // 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: 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 class with constructors

22 13-22 Implement Member Functions  The next few slides show the member function implementations  This is followed by a test driver for track  Each class must be tested at least by — calling every member function once — construct a vector of the objects (if they are to go into a container that is)

23 13-23 // file name: track.cpp #include "track.h" // for track's class def. // default constructor: track t1; track::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 ); track::track( string initTitle, seconds initPlayTime, seconds initPlayTime, int initCdNumber, int initCdNumber, int initTrackNumber ) int initTrackNumber ) { // 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;}

24 13-24 // file name: track.cpp continued // Accessing member functions seconds track::playTime() const { return my_playTime; return my_playTime;} int track::trackNumber() const { return my_trackNumber; return my_trackNumber;} int track::cdNumber() const { return my_cdNumber; return my_cdNumber;} string track::title() const { return my_title; return my_title;}

25 13-25 // This test driver call all member functions #include #include using namespace std; #include "track" int main() { // 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: Test driver calls all member functions I'm the Cat 235 or 3 minutes and 55 seconds track #1 CD #5 CD #5 Demo t_track.cpp

26 13-26 A first cut at CD class CD { // first draft public: string artist(); string artist(); string title(); string title();private: string my_artist; string my_artist; string my_title; string my_title; vector my_data; // many tracks vector my_data; // many tracks int my_size; // # of tracks int my_size; // # of tracks};

27 13-27 class CD final design class CD { public://--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 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

28 13-28 //--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 void first(); void first(); void next(); void next(); bool isDone() const; bool isDone() const; track currentItem() const; track currentItem() const;

29 13-29 // Data members: shouldn't matter to user // But they sure do matter to the implementers private: string my_artist; string my_artist; string my_title; string my_title; vector my_data; vector my_data; int my_size; int my_size; int my_index; int my_index; int my_cdNumber; int my_cdNumber;};

30 13-30 #include #include using namespace std; #include "cd" void show(const track & t2); // show the data stored on one track int main() { // 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

31 13-31 Show 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 objects with the iterator methods

32 13-32 A Free Function to help test 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: 1 5 Looking East 4:56 1 5 Looking East 4:56 Demo t_cd.cpp

33 13-33 Consider cdCollection  The cdCollection should be able to remove and add CDs this uses a vector to store CD objects class cdCollection { // third draft class cdCollection { // 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 my_data; vector my_data; int my_size; int my_size; }; }; Demo t_cdcollection.cpp

34 13-34 Summary of implementing individual classes  Each class can be designed like this — first as a CRH card — then as a class definition with action responsibilities listed as member function — then refine return types and parameters — add data members — add constructors — implement member functions — test the class at a minimum, call every method at a minimum, call every method

35 13-35 13.3 System Testing  Need to put everything together and test the entire system  In this case, consider a jukebox class that contains the major classes  Then jukebox can coordinate the activities between those objects  First consider the main function — see next slide

36 13-36 What int main might look like  Jukebox will start and stop things #include "jukebox" // for class jukebox #include "jukebox" // for class jukebox int main() // first draft int main() // 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

37 13-37 first cut at jukeBox  Jukebox contains the major objects class jukeBox { // first draft class jukeBox { // 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; }; };

38 13-38 Assessing the Design  Some examples of good design — A class that contains objects of another class should be sending messages to them Jukebox does this. If it didn't, you have extraneous objects in the class Jukebox does this. If it didn't, you have extraneous objects in the class — CDCollection does not know who contains it my_CdCollection does not send messages to Jukebox -- CDCollection could be reused my_CdCollection does not send messages to Jukebox -- CDCollection could be reused

39 13-39 Good Design?  Other examples of good design — The contained classes don't use each other — System intelligence is distributed well enough that Jukebox does very little consider the ease with which Jukebox gets the user desired selection based on the contents of the cdCollection consider the ease with which Jukebox gets the user desired selection based on the contents of the cdCollection my_currentSelection = my_currentSelection = my_trackSelector.getTrack(my_cdCollection) my_trackSelector.getTrack(my_cdCollection)


Download ppt "13-1 Computing Fundamentals with C++ Object-Oriented Programming and Design, 2nd Edition Rick Mercer Franklin, Beedle & Associates, 1999 ISBN 1-887902-36-8."

Similar presentations


Ads by Google