Nothing Stays the Same Chapter 5 HeadFirst OOAD Tom Perkins - NTPCUG
Dec 13, 2015
Inventory
addGuitar(string,double,GuitarSpec) getGuitar(string):Guitar search(GuitarSpec):Guitar[*]
GuitarSpecGuitar
serialNumber:stringprice:double
getSerialNumber():stringgetPrice():doublesetPrice():doublegetSpec():GuitarSpec
TypeBuilder Wood
model:stringnumStrings:int
getBuilder():BuildergetModel():StringgetType():TypegetBackWood():WoodgetTopWood():WoodgetNumStrings():intmatches(GuitarSpec):bool
toString():string toString():string toString:string
inventory *spec 1
builder 1type 1 topWood 1
backWood 1
Design Decision
• Guitar and Mandolin have many shared properties
• Create an Instrument class to store common properties and methods – abstract Base class
• Need new concrete classes Mandolin and MandolinSpec to handle mandolins
• Mandolin and Guitar will become “inherited classes”, subclasses, derived classes
Inherited Classes
• A new class, retains all members and functionality of a previously defined class
• You can add new members and functionality to new class
• Derived class extends base class
• Override functionality of base class
Public Class Truck
End Class
Public Class PickupTruck
Inherits Truck
End Class
public class Truck{}
public class PickupTruck : Truck {}
Abstract Classes
• Used to provide some invariant functionality in a class
• Cannot be instantiated – cannot create an object from an abstract class
• Some members can be overridden in inherited classes
Public MustInherit MyAbstractClass
End Class
public abstract MyAbstractClass {}
Abstract Classes
• Placeholders for actual implementation classes
• The abstract class defines the behavior; the subclasses implement that behavior
Guitar
serialNumber:stringprice:double
getSerialNumber():stringgetPrice():doublesetPrice():doublegetSpec():GuitarSpec
Mandolin
getSpec():MandolinSpec
Instrument
serialNumber:stringprice:double
getSerialNumber():stringgetPrice():doublesetPrice():doublegetSpec():GuitarSpec
Abstract class
Attributes common to Mandolin and Guitar moved to Instrument
Can’t create an instance of Instrument
Abstract class defines some basic behavior
Subclasses implement behavior
GuitarSpec
builder:Buildermodel:stringtype:TypebackWood:WoodtopWood:WoodnumStrings:int
getBuilder():BuildergetModel():StringgetType():TypegetBackWood():WoodgetTopWood():WoodgetNumStrings():intmatches(GuitarSpec):bool
MandolinSpec
builder:Buildermodel:stringtype:Typestyle:StylebackWood:WoodtopWood:WoodnumStrings:int
getBuilder():BuildergetModel():StringgetType():TypegetStyle():StylegetBackWood():WoodgetTopWood():WoodgetNumStrings():intmatches(MandolinSpec):bool
Style
toString():string
Inventory
addInstrument(string,double,GuitarSpec) get(string):Guitar search(GuitarSpec):Guitar[*]Search(MandolinSpec):Mandolin[*]
Instrument
serialNumber:stringprice:double
getSerialNumber():stringgetPrice():doublesetPrice():doublegetSpec():GuitarSpec
Mandolin Guitar
Full Diagram, Part I
InstrumentSpec
model:string
getBuilder():stringgetModel():stringgetType():TypegetBackWood():WoodgetTopWood():Woodmatches(InstrumentSpec):boolean
Mandolin
getNumStrings():Intmatches(GuitarSpec):bool
Guitar
Type
Builder
Wood
toString():string
toString():string
toString:string
builder 1
type 1
topWood 1
backWood 1
getStyle():Stylematches(MandolynSpec):bool
StyletoString():string
Full Diagram, Part II
Has Rick’s application become your career?
• For each added instrument, we have to create:– Instrument class– Create a new subclass for Instrument Spec
(BanjoSpec, FiddleSpec, etc)– Write a new search method for that instrument
in the Inventory class …
• “What a revolting development this is!” (William Bendix in The Life of Riley)
Some OO Principles
• “Code to an Interface, not an implementation”
• Encapsulation– Eliminate duplicate code– Encapsulate what varies (less probablity of
change)
• Cohesion – A class should do only one thing!
Toward one search Method …
public ArrayList search(GuitarSpec searchSpec) { ArrayList matchingGuitars = new ArrayList(); foreach (Instrument g in inventory) { if (g.getSpec().matches(searchSpec)) matchingGuitars.Add(g); } return matchingGuitars; } public ArrayList search(MandolinSpec searchSpec) { ArrayList matchingMandolins = new ArrayList(); foreach (Instrument g in inventory) { if (g.getSpec().matches(searchSpec)) matchingMandolins.Add(g); } return matchingMandolins; }
Try making InstrumentSpec a
concrete class
Improved (single) Search method public ArrayList search(InstrumentSpec searchSpec)
{
ArrayList matchingInstruments = new ArrayList();
foreach (Instrument g in inventory)
{
if (g.getSpec().matches(searchSpec))
matchingInstruments.Add(g);
}
return matchingInstruments;
}
See RicksConcreteInstrumentSpec.sln
Uses concrete InstrumentSpec, single search method
“What? A minor flaw in my design? Impossible!”
• It’s hard to change your own designs• Code once, look twice
– “Measure twice, saw once!”– Keep looking at your design when you run
into problems
• Peer programming• Design is iterative – not a single shot!• Major problem:
Modified DesignIndividual
InstrumentSpec
Classes
InstrumentSpec
properties:HashTablebuilder: Buildermodel:stringtype:InstrumentTypebackWood:WoodtopWood:Wood
getProperty(string):ObjectgetProperties():HashTablegetBuilder():stringgetModel():stringgetType():TypegetBackWood():WoodgetTopWood():Woodmatches(InstrumentSpec):boolean
Useful Links
• Good discussion of constructors in C#: http://www.yoda.arachsys.com/csharp/constructors.html
• Java to C# conversion – www.25hoursaday.com/CsharpVsJava.html