Unformatted text preview:

Good Design == Flexible Software (Part 2)Kenneth M. AndersonUniversity of Colorado, BoulderCSCI 4448/6448 — Lecture 10 — 09/25/2008© University of Colorado, 2008Thursday, September 25, 2008Lecture Goals• Review material from Chapter 5, part 2, of the OO A&D textbook• Good Design == Flexible Software• How to achieve flexible software• The Importance of Iteration• The Great Ease-Of-Change Challenge• Cohesive Classes• Discuss the Chapter 5 Example: Rick’s Guitars, Revisited• Emphasize the OO concepts and techniques encountered in Chapter 52Thursday, September 25, 2008Review: Our Three (Most Recent) OO Principles• Code to an Interface• If you have a choice between coding to an interface or an abstract base class as opposed to an implementation or subclass, choose the former• Let polymorphism be your friend• Encapsulate What Varies• Find the locations of your software likely to change and wrap them inside a class; hide the details of what can change behind the public interface of the class• Only One Reason To Change• Each class should have only one reason that can cause it to change• (the thing it encapsulates)3Thursday, September 25, 2008Rick’s Current Application4getBuilder(): BuildergetModel(): StringgetType(): TypegetBackWood(): WoodgetTopWood(): Woodmatches(InstrumentSpec): booleanmodel: StringInstrumentSpecBuilderTypeWoodbuildertopWoodbackWoodtypegetStyle(): Stylematches(InstrumentSpec): booleanMandolinSpecStylestylegetNumStrings(): intmatches(InstrumentSpec): booleannumStrings: intGuitarSpecGuitarMandolingetSerialNumber(): StringgetPrice(): doublesetPrice(double)getSpec(): InstrumentSpecserialNumber: Stringprice: doubleInstrumentspecaddInstrument(String, double, InstrumentSpec)get(Sring): Instrumentsearch(GuitarSpec): Guitar [*]search(MandolinSpec): Mandolin [*]Inventoryinventory*Thursday, September 25, 2008The Problems?• Inventory.addInstrument() has code specific to each instrument type• If we add a new Instrument subclass, we have to change this method.• The Inventory class has one search() method for each type of instrument• InstrumentSpec is an abstract class and we can’t instantiate it directly.• This means that we can’t search across instruments easily• Instrument subclasses don’t offer much functionality• Instrument does all the hard work.• Each time we add a new subclass to Instrument, we need to add a new subclass to InstrumentSpec5Thursday, September 25, 2008search() Upgrade• We start by looking at the problem of having multiple search() methods• one for each subclass of InstrumentSpec• This situation is simply not tenable… our system will never be flexible if we have to change Inventory’s public interface every time we want to add a new type of Instrument to our system!• Having a method for each subclass of InstrumentSpec feels like we are coding to implementations, violating the “code to an interface” principle• But, we had to do this because InstrumentSpec is abstract and we made it abstract since we wanted it to define a base class (or interface) for all of its possible subclasses• Recall that we created the GuitarSpec class in the first place to address the problem that Guitar was initially being asked to play two roles6Thursday, September 25, 2008public abstract class InstrumentSpec {12 private Builder builder;3 private String model;4 private Type type;5 private Wood backWood;6 private Wood topWood;78 public InstrumentSpec(Builder builder, String model, Type type,9 Wood backWood, Wood topWood) {10 this.builder = builder;11 this.model = model;12 this.type = type;13 this.backWood = backWood;14 this.topWood = topWood;15 }1617 public Builder getBuilder() {18 return builder;19 }2021 public String getModel() {22 return model;23 }2425 public Type getType() {26 return type;27 }2829 public Wood getBackWood() {30 return backWood;31 }3233 public Wood getTopWood() {34 return topWood;35 }3637 public boolean matches(InstrumentSpec otherSpec) {38 if (builder != otherSpec.builder)39 return false;40 if ((model != null) && (!model.equals("")) &&41 (!model.equals(otherSpec.model)))42 return false;43 if (type != otherSpec.type)44 return false;45 if (backWood != otherSpec.backWood)46 return false;47 if (topWood != otherSpec.topWood)48 return false;49 return true;50 }51}5253If you look closely you’ll see that there is NOTHING abstract about InstrumentSpec! 7Thursday, September 25, 2008search Upgrade• To follow the “code to an interface” design principle (in this context), lets try making InstrumentSpec a concrete class• This would allow us to instantiate the class directly• We can eliminate all of the instrument-specific search() methods and replace it with a single method with the signature• public List search(InstrumentSpec searchSpec);• Do we lose functionality with this approach?• Not really. If we want to do an instrument-specific search, just pass in a subclass of InstrumentSpec. This is what we had already• Do we gain functionality with this approach?• Yes! We can search for more than one type of Instrument by passing in an InstrumentSpec that contains attributes shared by all instruments8Thursday, September 25, 2008search() Upgradepublic List search(GuitarSpec searchSpec) {1 List matchingGuitars = new LinkedList();2 for (Iterator i = inventory.iterator(); i.hasNext(); ) {3 Guitar guitar = (Guitar)i.next();4 if (guitar.getSpec().matches(searchSpec)) {5 matchingGuitars.add(guitar);6 }7 }8 return matchingGuitars;9}1011public List search(MandolinSpec searchSpec) {12 List matchingMandolins = new LinkedList();13 for (Iterator i = inventory.iterator(); i.hasNext(); ) {14 Mandolin mandolin = (Mandolin)i.next();15 if (mandolin.getSpec().matches(searchSpec)) {16 matchingMandolins.add(mandolin);17 }18 }19 return matchingMandolins;20}2122search(): the old way!9Thursday, September 25, 2008search() Upgradepublic List search(InstrumentSpec searchSpec) {1 List results = new LinkedList();2 for (Iterator i = inventory.iterator(); i.hasNext(); ) {3 Instrument instrument = (Instrument)i.next();4 if (instrument.getSpec().matches(searchSpec)) {5 results.add(instrument);6 }7 }8 return results;9}1011search(): the new way. Can search across all instruments; can perform instrument-specific searches via substitutability and polymorphism10Thursday, September 25,


View Full Document

CU-Boulder CSCI 6448 - Flexible Software (Part 2)

Documents in this Course
Struts

Struts

12 pages

Adapter

Adapter

23 pages

Prototype

Prototype

16 pages

Weka

Weka

15 pages

qooxdoo

qooxdoo

16 pages

Django

Django

12 pages

Overview

Overview

22 pages

XNA

XNA

5 pages

Load more
Download Flexible Software (Part 2)
Our administrator received your request to download this document. We will send you the file to your email shortly.
Loading Unlocking...
Login

Join to view Flexible Software (Part 2) and access 3M+ class-specific study document.

or
We will never post anything without your permission.
Don't have an account?
Sign Up

Join to view Flexible Software (Part 2) 2 2 and access 3M+ class-specific study document.

or

By creating an account you agree to our Privacy Policy and Terms Of Use

Already a member?