Chapter 5(part 2): good design = flexible software OO principles can really loosen up your application and you’ll see how higher cohesion can really help your coupling OO Principles • Encapsulate what varies. • Code to an interface rather than to an implementation. • Each class in your application should have only one reason to change. A closer look at the search() method • It seems pretty clear that there’s a problem with the way we’re handling searches for Rick’s clients. We could make InstrumentSpec a concrete class. Problems with Search() • The search method isn’t the only thing that makes adding new instruments for each new instrument type. – Why is there a need for an Instrument class in Rick’s application? – What things are common to all instruments? – What things are different between instruments? • Why is there a need for an Instrument class in Rick’s application? – Most instruments have at least a few common properties, like serial number and price. Instrument stores the common properties, and then each specific instrument type can extend from Instrument. • What things are common to all instruments? – The serial number, the price, and some set of specifications (even though the details of those specs may be different for different instrument types). • What things are different between instruments? – The specifications: each type of instrument has a different set of properties that it can contain. And since each instrument has a different InstrumentSpec, each has a different constructor. All the instruments—at least from Rick’s perspective—behave the same. Two reasons to have sub classes for each instrument type: • Because the Instrument class represents a concept, and not an actual object, it really should be abstract. So we have to have subclasses for each instrument type. • Each different type of instrument has different properties, and uses a different subclass of InstrumentSpec, so we need an instrument-specific constructor for each type of instrument. • But we’re ending up with lots of extra classes that don’t do much… • Remember the second step in writing great software – Apply basic OO principles to add flexibility. Important OO Principles: • Inheritance – We’re using inheritance already with the Instrument class. • Polymorphism – We use polymorphism in the search() method to treat all instruments as instances of Instrument, so searching is a lot easier. • Abstraction – InstrumentSpec abstracts the details about each instruments specifications away from the Instrument class itself. • Encapsulation – We’re using encapsulation a lot, but maybe we can use it even more… remember, encapsulate what varies! The properties in each instrument type are what varies, can we somehow encapsulate those properties away from Instrument and InstrumentSpec completely? The key is encapsulation. • Encapsulate what varies: • The properties for each instrument are what varies in the application. • That’s why we have all of those subclasses of Instrument, like Guitar and Mandolin. • The behavior of each instrument doesn’t vary, so do we really need subclasses? • Make Instrument a concrete class and get rid of all those instrument-specific subclasses. • What about the properties that vary? • The Instrument class has a reference to an InstrumentSpec, and all the property differences can be handled. – We actually already have the properties encapsulated away from the rest of the application! • One of the hardest things you will ever do is to let go of mistakes you made in your own designs. • Because it seemed to make sense at the time, and it’s HARD to change something you thought was already working! • Design is iterative… and you have to be willing to change your own designs. – Pride kills good design “Double Encapsulation” in Rick’s Software • The problem is that these properties vary across instrument. Getting Dynamic with Instrument Properties • Use a Map to handle various types of properties, and we’ll still be able to easily add new properties at any time. • When you have a set of properties that vary across your objects, use a collection, like a Map, to store those properties dynamically. • You’ll remove lots of methods from your classes, and avoid having to change your code when new properties are added to your app. • Most good designs come from analysis of bad designs. • Never be afraid to make mistakes and then change things around. How cohesive is your software really? • How easy is it to change Rick’s software? • Is Rick’s software really well-designed? • And what the heck does cohesive mean? How easy is it to change Rick’s search tool? • How many classes did you have to add to support Rick’s new instrument types? – None! We got rid of all the instrument-specific subclasses of Instrument and InstrumentSpec. • How many classes did you have to change to support Rick’s new Instrument types? – One: we need to add any new instrument types to the InstrumentType enumerated type. • Suppose that Rick decided that he wanted to start keeping up with what year an instrument was made in. How many classes would you need to change? – None! You can just store the year that an instrument was made in the properties Map in InstrumentSpec. • Rick also wants to add a new property, neckWood. How many classes would you need to change? – One in the worst case, and maybe none! neckWood is just another property. Our software is easy to change… but what about that “cohesive” thing? • A cohesive class does one thing really well and dose not try to do or be something else. • Cohesion measures the degree of connectivity among the elements of a single module, class, or object. The higher the cohesion of your software is, the more well-defined and related the responsibilities of each individual class in your application. Each class has a very specific set of closely related actions it performs. • If each class does just a few things that are all grouped together, then it’s probably a highly cohesive piece of software. But if you have one class doing all sorts of things that aren’t that closely related, you’ve probably got low cohesion. • Highly cohesive software is loosely coupled. – The more cohesive your software is, the looser the coupling between classes. • High cohesion is better than low cohesion • Software that’s cohesive be easier to reuse, as well as change Analysis and Design • Well designed software is easy to change and extend. • Use basic OO principles like encapsulation and inheritance to make your software more flexible. • If a design isn't flexible, then CHANGE IT! Never settle on bad design, even if it’s your bad design that has to change. • Make sure each of your classes is cohesive: each of your classes should focus on doing ONE THING really well. • Always strive for higher cohesion as you move through your software’s design life cycle. OO Principles • Encapsulate what varies. • Code to and interface rather than to an implementation. • Each class in your application should have only one reason to change. • Classes are about behavior and functionality.
Pages to are hidden for
"5_part 2_ god design = flexible software"Please download to view full document