CS 151 ObjectOriented Design August 27 Class Meeting
CS 151: Object-Oriented Design August 27 Class Meeting Department of Computer Science San Jose State University Fall 2013 Instructor: Ron Mak www. cs. sjsu. edu/~mak
Key Points from Last Week on Good Design o There is no magic formula. n o It’s an iterative process. n n o Start with a workable initial design. Each iteration builds upon working code to improve the design. One good design technique: encapsulation. n n n o Every good design is achieved after a journey. Encapsulate the code that will vary. Isolate the changes from the rest of the code. Encapsulation supports code reliability and flexibility (how? ). The design/code/test iterations are part of the overall “big picture” to develop a software application. n No “big bang”! SJSU Dept. of Computer Science Spring 2013: August 27 CS 151: Object-Oriented Design © R. Mak 2
Application Development Big Picture SJSU Dept. of Computer Science Spring 2013: August 27 CS 151: Object-Oriented Design © R. Mak 3
Iterative Development SJSU Dept. of Computer Science Spring 2013: August 27 CS 151: Object-Oriented Design © R. Mak 4
Incremental Development Goal Start o o Each iteration adds functionality to code that already works. No Big Bang! _ From: Head First Object-Oriented Analysis & Design, O’Reilly, 2006. SJSU Dept. of Computer Science Spring 2013: August 27 CS 151: Object-Oriented Design © R. Mak 5
Rick’s Guitar Application What made us believe that this is a good design? From: Head First Object-Oriented Analysis & Design, O’Reilly, 2006. SJSU Dept. of Computer Science Spring 2013: August 27 CS 151: Object-Oriented Design © R. Mak 6
A New Requirement! o Rick changes the name of his shop to Rick’s Music. o He adds mandolins to the type of instruments he sells. o How easily can our software design accommodate this change? SJSU Dept. of Computer Science Spring 2013: August 27 CS 151: Object-Oriented Design © R. Mak 7
Possible Mandolin Solutions o Add a Mandolin class. n o Replace the Guitar class with an Instrument class. n o Cut and paste code from the existing Guitar class. A type field indicates whether the instrument is a guitar or a mandolin. Add a new Instrument class. n Make the existing Guitar class and a new Mandolin class subclasses of the Instrument class. Solution Advantages Disadvantages Mandolin class Simple to implement • Duplicate code • Hard to maintain Instrument class with type field No duplicate code • Not an O-O solution • Need to check type on objects Instrument base class • O-O solution • No type field to check • No duplicate code Does Rick have an Instrument in the inventory? SJSU Dept. of Computer Science Spring 2013: August 27 CS 151: Object-Oriented Design © R. Mak From: Head First Object-Oriented Analysis & Design, O’Reilly, 2006. 8
New Instrument Class o Add a new Instrument class. n o Make the existing Guitar class and a new Mandolin class subclasses of the Instrument class. Change the Inventory class to contain a list of Instrument objects instead of only Guitar objects. n Each Instrument object can be either a Guitar object or a Mandolin object. o It doesn’t make sense to create Instrument objects directly, only Guitar and Mandolin objects. o Therefore, make the Instrument class abstract. n Make the Instrument class the abstract base class of the Guitar and Mandolin subclasses. _ SJSU Dept. of Computer Science Spring 2013: August 27 CS 151: Object-Oriented Design © R. Mak 9
Abstract Classes o An abstract class is a placeholder for the actual implementation classes. n The abstract class defines the behavior, and the subclasses implement that behavior. n The abstract class encapsulates shared behavior and defines the protocol for all its subclasses. _ SJSU Dept. of Computer Science Spring 2013: August 27 CS 151: Object-Oriented Design © R. Mak 10
New Instrument. Spec Class o Add a new abstract Instrument. Spec class. n o Base class for the Guitar. Spec and Mandolin. Spec subclasses. The Instrument class has a one-to-one association with the Instrument. Spec class. _ SJSU Dept. of Computer Science Spring 2013: August 27 CS 151: Object-Oriented Design © R. Mak 11
Next Iteration Design From: Head First Object-Oriented Analysis & Design, O’Reilly, 2006. SJSU Dept. of Computer Science Spring 2013: August 27 CS 151: Object-Oriented Design © R. Mak 12
New Instrument Class public abstract class Instrument { private String serial. Number; private double price; private Instrument. Spec spec; public Instrument(String serial. Number, double price, Instrument. Spec spec) { this. serial. Number = serial. Number; this. price = price; this. spec = spec; } public String get. Serial. Number() { return serial. Number; }. . . } SJSU Dept. of Computer Science Spring 2013: August 27 CS 151: Object-Oriented Design © R. Mak 13
New Instrument. Spec Class o Common base class attributes. public abstract class Instrument. Spec { private Builder builder; private String model; private Type type; private Wood back. Wood; private Wood top. Wood; public Instrument. Spec(Builder builder, String model, Type type, Wood back. Wood, Wood top. Wood) { this. builder = builder; this. model = model; this. type = type; this. back. Wood = back. Wood; this. top. Wood = top. Wood; }. . . SJSU Dept. of Computer Science } Spring 2013: August 27 CS 151: Object-Oriented Design © R. Mak 14
New Instrument. Spec Class, cont’d o Match base class attributes only. public boolean matches(Instrument. Spec other. Spec) { if (builder != other. Spec. builder) return false; if ((model != null) && (!model. equals("")) && (!model. equals(other. Spec. model))) return false; if (type != other. Spec. type) return false; if (back. Wood != other. Spec. back. Wood) return false; if (top. Wood != other. Spec. top. Wood) return false; return true; } SJSU Dept. of Computer Science Spring 2013: August 27 CS 151: Object-Oriented Design © R. Mak 15
Revised Inventory Class public class Inventory { private List inventory; . . . public void add. Instrument(String serial. Number, double price, Instrument. Spec spec) { Instrument instrument = null; if (spec instanceof Guitar. Spec) { instrument = new Guitar(serial. Number, price, (Guitar. Spec) spec); } else if (spec instanceof Mandolin. Spec) { instrument = new Mandolin(serial. Number, price, (Mandolin. Spec) spec); } inventory. add(instrument); } } SJSU Dept. of Computer Science Spring 2013: August 27 CS 151: Object-Oriented Design © R. Mak 16
Revised Inventory Class, cont’d public List search(Guitar. Spec search. Spec) Search for { List matching. Guitars = new Linked. List(); for (Iterator i = inventory. iterator(); i. has. Next(); ) { Guitar guitar = (Guitar) i. next(); if (guitar. get. Spec(). matches(search. Spec)) { matching. Guitars. add(guitar); } } return matching. Guitars; } guitars. Search for mandolins. public List search(Mandolin. Spec search. Spec) { List matching. Mandolins = new Linked. List(); for (Iterator i = inventory. iterator(); i. has. Next(); ) { Mandolin mandolin = (Mandolin) i. next(); if (mandolin. get. Spec(). matches(search. Spec)) { matching. Mandolins. add(mandolin); } } Overloaded search() methods. return matching. Mandolins; } SJSU Dept. of Computer Science Spring 2013: August 27 CS 151: Object-Oriented Design © R. Mak 17
Guitar and Mandolin Classes public class Guitar extends Instrument { public Guitar(String serial. Number, double price, Guitar. Spec spec) { super(serial. Number, price, spec); } } What’s the difference between these two classes? public class Mandolin extends Instrument { public Mandolin(String serial. Number, double price, Mandolin. Spec spec) { super(serial. Number, price, spec); } } SJSU Dept. of Computer Science Spring 2013: August 27 CS 151: Object-Oriented Design © R. Mak 18
Revised Guitar. Spec Class public class Guitar. Spec extends Instrument. Spec { private int num. Strings; . . . // Override the superclass matches() public boolean matches(Instrument. Spec other. Spec) { if (!super. matches(other. Spec)) return false; Match base class attributes. if (!(other. Spec instanceof Guitar. Spec)) return false; Guitar. Spec spec = (Guitar. Spec) other. Spec; if (num. Strings != spec. num. Strings) return false; return true; } } SJSU Dept. of Computer Science Spring 2013: August 27 CS 151: Object-Oriented Design © R. Mak 19
New Mandolin. Spec Class public class Mandolin. Spec extends Instrument. Spec { private Style style; . . . // Override the superclass matches() public boolean matches(Instrument. Spec other. Spec) { if (!super. matches(other. Spec)) return false; Match base class attributes. if (!(other. Spec instanceof Mandolin. Spec)) return false; } } Mandolin. Spec spec = (Mandolin. Spec) other. Spec; if (!style. equals(spec. style)) return false; return true; What’s the difference between the two matches() methods? SJSU Dept. of Computer Science Spring 2013: August 27 CS 151: Object-Oriented Design © R. Mak 20
Take roll! SJSU Dept. of Computer Science Spring 2013: August 27 CS 151: Object-Oriented Design © R. Mak 21
Any Red Flags? o Duplicated code n n o Guitar and Mandolin classes Guitar. Spec and Mandolin. Spec classes Overloaded search() methods in class Inventory: public List search(Guitar. Spec search. Spec) { List matching. Guitars = new Linked. List(); for (Iterator i = inventory. iterator(); i. has. Next(); ) { Guitar guitar = (Guitar) i. next(); if (guitar. get. Spec(). matches(search. Spec)) { matching. Guitars. add(guitar); } } public List search(Mandolin. Spec search. Spec) return matching. Guitars; { } List matching. Mandolins = new Linked. List(); for (Iterator i = inventory. iterator(); i. has. Next(); ) { Mandolin mandolin = (Mandolin) i. next(); if (mandolin. get. Spec(). matches(search. Spec)) { matching. Mandolins. add(mandolin); } } return matching. Mandolins; } SJSU Dept. of Computer Science Spring 2013: August 27 CS 151: Object-Oriented Design © R. Mak 22
More Red Flags? o Serial type tests, such as in method add. Instrument() in class Inventory: public void add. Instrument(String serial. Number, double price, Instrument. Spec spec) { Instrument instrument = null; if (spec instanceof Guitar. Spec) { instrument = new Guitar(serial. Number, price, (Guitar. Spec) spec); } else if (spec instanceof Mandolin. Spec) { instrument = new Mandolin(serial. Number, price, (Mandolin. Spec) spec); } inventory. add(instrument); } SJSU Dept. of Computer Science Spring 2013: August 27 CS 151: Object-Oriented Design © R. Mak 23
Rick Wants More Instruments! YIKES! Our design doesn’t scale very well. . . SJSU Dept. of Computer Science Spring 2013: August 27 CS 151: Object-Oriented Design © R. Mak From: Head First Object-Oriented Analysis & Design, O’Reilly, 2006. 24
Our Design Doesn’t Scale Very Well o For each new instrument: n We need to add a subclass of Instrument. Spec. n In class Inventory, we need to add: n o o a new search() method a new type test in the add. Instrument() method _ SJSU Dept. of Computer Science Spring 2013: August 27 CS 151: Object-Oriented Design © R. Mak 25
Time to Revisit Our Design! o Having all those Instrument and Instrument. Spec subtypes may not be such a good idea after all. o What varies among the instrument classes? n n o properties matching algorithm What should we do with stuff that varies? What doesn’t vary? n n manufacturer type price serial number SJSU Dept. of Computer Science Spring 2013: August 27 CS 151: Object-Oriented Design © R. Mak 26
Encapsulation to the Rescue! o If we can encapsulate the varying instrument properties in one place. . . n n o Instrument properties vary across the instrument types. n o We can get rid of all the Instrument and Instrument. Spec subclasses. Then both the Instrument and Instrument. Spec classes can become concrete classes (instead of being abstract). A guitar has some different properties than mandolins. Encapsulate the varying properties in a hash table. n n property name : property value pairs Each type of instrument can have a different set of properties. _ SJSU Dept. of Computer Science Spring 2013: August 27 CS 151: Object-Oriented Design © R. Mak 27
Revised Instrument. Spec Class public class Instrument. Spec { private Map properties; public Instrument. Spec(Map properties) { if (properties == null) { this. properties = new Hash. Map(); } else { this. properties = new Hash. Map(properties); } }. . . SJSU Dept. of Computer Science Spring 2013: August 27 CS 151: Object-Oriented Design © R. Mak 28
Revised Instrument. Spec Class, cont’d public boolean matches(Instrument. Spec other. Spec) { // Loop over the property keys in the hashmap. for (Iterator i = other. Spec. get. Properties(). key. Set(). iterator(); i. has. Next(); ) { // Do all the properties match? String property. Name = (String) i. next(); if (!properties. get(property. Name). equals(other. Spec. get. Property(property. Name))) { return false; } } return true; } This is a generic matching algorithm that works with any instrument type’s properties. SJSU Dept. of Computer Science Spring 2013: August 27 CS 151: Object-Oriented Design © R. Mak 29
Re-revised Inventory Class public class Inventory { private List inventory; . . . public void add. Instrument(String serial. Number, double price, Instrument. Spec spec) { Instrument instrument = new Instrument(serial. Number, price, spec); inventory. add(instrument); }. . . SJSU Dept. of Computer Science Spring 2013: August 27 CS 151: Object-Oriented Design © R. Mak 30
Re-revised Inventory Class, cont’d public List search(Instrument. Spec search. Spec) { List matching. Instruments = new Linked. List(); for (Iterator i = inventory. iterator(); i. has. Next(); ) { Instrument instrument = (Instrument) i. next(); if (instrument. get. Spec(). matches(search. Spec)) { matching. Instruments. add(instrument); } } return matching. Instruments; } } Only one search() method needed! SJSU Dept. of Computer Science Spring 2013: August 27 CS 151: Object-Oriented Design © R. Mak 31
Improved Design SJSU Dept. of Computer Science Spring 2013: August 27 CS 151: Object-Oriented Design © R. Mak From: Head First Object-Oriented Analysis & Design, O’Reilly, 2006. 32
Improved Design, cont’d From: Head First Object-Oriented Analysis & Design, O’Reilly, 2006. SJSU Dept. of Computer Science Spring 2013: August 27 CS 151: Object-Oriented Design © R. Mak 33
Conclusions o It takes a journey to achieve Good Design n o iterative improvements wrong paths backtracking Developing Great Software can be a messy business! n Be willing to fix your own bad design decisions. _ SJSU Dept. of Computer Science Spring 2013: August 27 CS 151: Object-Oriented Design © R. Mak 34
- Slides: 34