180 likes | 194 Views
Explore the challenges and solutions of software component design with a focus on code refactoring for improved cohesion. Learn about inheritance, abstract classes, concrete classes, and embracing the Strategy Pattern to address behavior variations in Java programming. Discover the implications of multiple levels of abstraction, avoiding class explosions, and the benefits of interface inheritance. Dive into strategies for sorting algorithms and applying the Strategy Design Pattern in software development.
E N D
SE-2811Software Component Design • Week 1, Day 2 SE-2811 Dr. Josiah Yoder Slide style: Dr. Hornick
Refactoring to improve cohesion via use of OO Inheritance Duck: an abstract class • Abstract classes can define attributes and (default) behaviors common to all Duck-derived classes. Concrete classes implement type-specific adaptations (overrides) • These may also include additional type-specific attributes (none in this case) SE-2811 Dr. Mark L. Hornick SimUDuck v2
Is inheritance always a solution? What if some ducks (Mallards, Redheads) had similar behavior: • Quacking sound • Circular swimming pattern While others (Pintail) had different behaviors: • Quacking sound • Random swimming (ie floating) pattern And still others (Decoys) had: • No quacking sound • Random swimming (ie floating) pattern Lots of overriding (and maybe duplication of code)!Q1) Should we bother implementing any behaviors at all in the Duck abstract class if many will be overridden anyway (and possibly duplicated)? Q2) Can we modify the class hierarchy to group similar behaviors together? Code duplication? SE-2811 Dr. Mark L. Hornick
What about multiple levels of abstraction? Here, the swim() and quack() behavior is defined, but not implemented, in Duck… …instead, swim() and quack() behaviors are implemented in a second level of abstract classes... …and finally inherited in concrete classes. And what about a quiet, swimming Duck? SE-2811 Dr. Mark L. Hornick SimUDuck v3
BUT: Multiple inheritance is not even allowed in Java!(FYI: it IS allowed in C++, but is EVIL) Here, the swim() and quack() behavior is defined, but not implemented, in Duck… …instead, swim() and quack() behaviors are implemented in a second level of abstract classes... …and finally inherited in concrete classes. SE-2811 Dr. Mark L. Hornick SimUDuck v3
This can also lead to messy “class explosions” SE-2811 Dr. Mark L. Hornick SimUDuck v3
Some reflections on inheritance… Allan Holub (a noted computer technology author) once attended a Java user group meeting where James Gosling (Java's inventor) was the featured speaker. During the memorable Q&A session, he asked him [Gosling]: Q: "If you could do Java over again, what would you change?" Gosling: "I'd leave out classes.” After the laughter died down, he explained that the real problem wasn't classes per se, but rather implementation inheritance (the extends relationship). Interface inheritance (the implements relationship), Gosling explained, is preferable. SE-2811 Dr. Mark L. Hornick
We can use interface inheritance to address these concerns… We eliminate implementation in abstract classes, and force concrete classes to supply it instead. …but now we’re back to the duplication of code problem that we saw in v2! SE-2811 Dr. Mark L. Hornick SimUDuck v4
A different approach: Isolate behaviors that vary, and encapsulate them as attributes to eliminate implementation inheritance and class explosions: SE-2811 Dr. Mark L. Hornick SimUDuck v5
Sorting Example • Suppose we have a program that sorts Class objects • Perhaps alphabetically, perhaps by “closeness of fit” • Perhaps using Bubble Sort, or a (much better) algorithm like Merge Sort. PLEASE IGNORE SE-2811 Dr. Mark L. Hornick
A Strategy for Comparing [Collections.sort()] Collections.sort() implements an argument which is a reference to a concrete class that implements the Comparator interface, and thus the behavior of the compare() method. Depending on the strategy of the compare() method in the concrete class, different sorting will be used by Collections.sort(). The comparison strategy is decoupled from the Collections.sort() method itself. SE-2811 Dr. Mark L. Hornick
A Strategy for Sorting PLEASE IGNORE • Different strategies for sorting • MergeSort O(NlogN) • QuickSort O(NlogN) • ShellSort In-place, Ω(N(logN/log logN)2) • InsertionSort O(N2) • BubbleSort O(N2) • Cool sorting algorithms of the future (or past) … • Would be nice to “plug in” new strategies SE-2811 Dr. Josiah Yoder Idea: http://fuchangmiao.blogspot.com/2007/10/strategy-vs-observer.html
The Strategy Design Patternin its general form: The Context is the class that encapsulates and usesa specific behavior, or Strategy. A Strategy is an interfacethat defines a behavior ConcreteStrategy classes implement specific behaviors
The Duck App in Code – v0 SE-2811 Dr. Josiah Yoder Slide style: Dr. Hornick
Applying the Strategy Pattern: Evidence 1 The Strategy Pattern is a behavioral pattern usually considered and applied at design-time. Premise: Your application requires similar objects whose behavior varies. SE-2811 Dr. Mark L. Hornick
Applying the Strategy Pattern: Evidence 2 As a designer, you watch for inheritance patterns that result in excessive behavior overrides and/or code duplication among classes. SE-2811 Dr. Mark L. Hornick
Applying the Strategy Pattern: Action!(Code v5) Leave behavior that is truly shared in abstract classes. Isolate behavior(s) that vary and declare interfaces that define those behaviors Implement the behaviors in separate concrete classes whose references can be passed to the Duck ctor SE-2811 Dr. Mark L. Hornick