Object Oriented Design
A design is a blueprint for the software structure, including
- technologies (platforms, programming languages, frameworks/libraries) used;
- overall deployment architecture if more than one computer is involved;
- class names and structure (this is object-oriented design after all)
We are focusing only on the last one in this class, you are being given the first two.
Starting a Design
How to start?
- Get the developers together (i.e. your project group), find a whiteboard and get going!
- Focus on the key features (the most important ones, not special or corner cases) in the initial design.
- A good way to get off the ground is textual analysis.
Begin with textual analysis
Look at all the English text describing your requirements.
- Potential classes are nouns (the things)
- Potential member functions in the classes are verbs.
- Any text can be mined, e.g. for chess find a webpage with the rules on it.
- This simple approach can work surprisingly well.
UML Class diagrams in brief
UML class diagrams let you sketch your initial design ideas and how classes relate on paper or whiteboard.
Classes
- Each class is a rectangle
- put class name; line; data members (UML calls them "attributes"); line; member functions (UML calls them "methods")
- example where
Dollarsis assumed to be a class type - The standard is to use
variable : typenotation as in the above, but we can just use the C/C++ form oftype variablein our diagrams
Class relationships
- See this site for UML symbols and examples of different relationships between classes
- Inheritance: use an open arrow from derived to base class to show inheritance ("is-a")
- Associations are shown simply as a line from one class to another
- At the conceptual level they mean two classes are closely interacting with each other
- At a high level, an association implies one may access or change the another;
- At the implementation level they might imply one having the other as a data member
- Singular has-a relationships are associations (ie, a field is a member of another class).
- Aggregation is when a collection of items from one class is a member of another class and represented with a diamond symbol on the containing class
Attributes (aka data members / fields)
- In a UML class diagram, the attributes represent what the C++ data members might be
- Generally for simplicity if there is an association between two classes or a getter member function you don't also need to show the attribute in the class
The above only covers the most basic features; if you want more information, here is a tutorial from IBM
Design refinement tips
- Think about an individual class' responsibilities; make any responsibility or action a class needs a member function of the class (with an evocative name so you will remember what its supposed to do)
- Play out different use-cases over the class diagram and make sure there is a class and member function responsible for implementing each action in the use-case
- If a class has no member functions that probably means its not doing anything; throw it out
- If two or more classes are similar but not quite the same, make an abstract superclass of them containing the shared functionality - let inheritance emerge; don't force it
Design Pitfalls in a nutshell
- The Data-centric design trap
- A data-centric design has classes with no meaningful member functions - they are just passive data holders
- Data-centric designs tend to have a couple really fat classes doing all the operations and a bunch of tiny classes that just passively hold data
- Data-centric designs should be refactored to push methods from the big class out to the data classes
- Example of a bad data-centric design for chess: pieces that are basically
structs with no meaningful member functions and all the member functions are in theBoardorGameclass
- The Over-eager inheritance trap
- In many cases there may be is-a relationships where all there is no real code difference between the base and derived classes
- In this case simply don't inherit
- Example: making a class
Suitwith subclassesSpadeSuit,HeartSuit,DiamondsSuit,ClubsSuithas nice is-a properties but the code is pretty much the same so in nearly all card games there is no meaningful inheritance there - If you have derived classes with no new or overriden methods other than constructors/getters/setters than you likely have unnecessary inheritance
- The
switchsmell- If your code has lots of
switchorifstatements, it often means the decision being made could instead be based on which subclass you have at run-time and so you don't need toswitch. - An example in chess is if the
move()function was all in the mainGameand just did a bigswitchon which type of piece was being moved. Don't do that, put themove()action on thePieceand override as needed.
- If your code has lots of
Evolution of Initial Designs to Code
The first step is to take the proposed classes and member functions and map them on to class templates
- Create a C++ header file for each proposed class. At the top write a brief comment describing the purpose of the class.
- For classes closely associated with each other, consider making a data member in one to give access to the other.
- Proposed member functions become C++ member functions in your
.hfile. - Put types in your
.hfile if they are clear, and use()andvoidif not.
Teamwork
Pair Programming utilizes driver/navigator roles and implements the “two heads are better than one” approach:
- Driver is the only person with hands on the keyboard
- Navigator is looking out for the bigger picture and for errors made by driver
- Take turns in roles
- Highly recommended that you try out pair programming
Teamwork: the Good ..
- Open and frequent communication
- Multiple perspectives & ideas
- Sharing of work according to abilities
- Planning
- Asking for help
- Sharing code/work (commit early, commit often)
- Compromise approaches:
- Try several, pick best
- Take turns
- Find middle ground
… the Bad …
- Can't agree on things
- Scheduling work with partners
- People don't pull their weight
- Time management & expectations
- People not properly integrating their code
… and the Ugly
- One person does all the work
- Procrastinating, not getting things done