350 likes | 501 Views
Chapter 25. More Design Patterns. Polymorphism. Issue: Conditional variation If-then-else or switch statements New variation or case: Conditional statements change Often in many places (methods, classes) Makes it difficult to extend program, add new variations Examples
E N D
Chapter 25 More Design Patterns
Polymorphism • Issue: Conditional variation • If-then-else or switch statements • New variation or case: • Conditional statements change • Often in many places (methods, classes) • Makes it difficult to extend program, add new variations • Examples • Alternatives based on type • Pluggable software components: • Replace one server with another • Without affecting the clients
Polymorphism • Solution • Do not test for the type of an object and use conditional logic • Use polymorphic operations instead • Example: Third-party tax calculator programs in the NextGen POS system • We want to use an “adapter class” • We call adapter’s methods, adapter converts it to tax calculator’s methods • We’d like our code not to depend on which tax calculator we use • We’d like to avoid conditional statements in the adapter class • Solution: Use one adapter class per tax calculator • Use polymorphism
Polymorphism in Monopoly • Issue: Different actions need to be performed when player lands on different types of square • Examples: • Go square: Get $200 • Tax square: Pay income tax (10% or $200) • Regular square: Do nothing (for now) • Solution: Use abstract superclass, Square • RegularSquare, TaxSquare, IncomeTaxSquare subclasses
Issue: How to adapt interaction diagrams to this change? May use “sd” and“ref” frames here to be more formal
Another polymorphic case • Notice design change: • Now Player knows location, instead of Piece • Decreases coupling • In fact, we realize “piece” class not really needed
When to use interfaces vs. abstract superclasses? • Use interfaces whenever you can • Because of single inheritance, abstract classes are restrictive • Unless there are a lot of default method implementations inherited – then use abstract classes
Design Pattern: Pure Fabrication • Idea: Make up (“fabricate”) new class with no direct equivalent concept in the domain • When other design patterns do not offer solutions with low coupling and high cohesion • Recall example: Saving a Sale object in a database • What goes wrong if “Sale” saves itself? • Task requires a lot of supporting database operations • Sale has to be coupled to the db interface • Saving to db a general task • A lot of other classes need the same support • Lots of duplication in each object
Solution: New “PersistentStorage” class • Persistent storage not a domain concept • We grouped a number of responsibilities into this class • Similar issue in Monopoly: • Player rolls dice: Not reusable in another game • Summing of dice done by player • Can’t ask for dice total without rolling again • Improved design: Fabricate “Cup” class that does the jobs above
Design of Objects • Design of objects done in one of two ways • Objects chosen by representational decomposition • Representing domain objects • Example: • TableOfContents • Objects chosen by behavioral decomposition • Group a number of related operations into a class • Example: • Algorithm object: TableOfContentsGenerator • Don’t overdo fabrication • If you put all functionality in one class, you end up writing a C program
Design Pattern: Indirection • Issue: How to avoid coupling between two or more things • Why? One is likely to change a lot. Don’t want the other to depend on it. • Solution: Use indirection. Create intermediate object. • Example: TaxCalculatorAdapter • Our design is independent from the third party tax program API • If the API changes, we only modify the adapter. • Example: PersistentStorage • Just change PersistentStorage to use a different database
Design Pattern: Protected Variations • Issue: How to design objects, subsystems and systems so that variations or instability in these elements do not have an undesirable impact on others? • Solution: • Identify points of predicted variations and instability • Put a stable interface around them to protect the rest of the design • Example: External tax calculator and the class hierarchy of adapters
Examples of Mechanisms Motivated byProtected Variations • Data-driven designs: • Example: Web-page style sheet read separately from the .html file • Service look-up mechanisms: JNDI, Jini, UDDI • Protects designs from where services are located • Interpreter-Driven Designs • Virtual machines, language interpreters, ... • Reflective or Meta-Level Designs • Java Beans • A way to learn what attribute or bean property a “Bean” has and what method to use to access it
Law of Demeter In any method M attached to a Class C, only methods defined by the following classes may be used: • The instance variable classes of C • the argument classes of the method M including C itself • Note: Global objects or the local objects of M are considered arguments of M
Law of Demeter (weak) In any method M attached to a Class C, data can be accessed and messages can be sent to only the following objects: • the arguments of the method M including self • The instance variables for the receiver of the message. • Global objects • the local objects of M
Law of Demeter (strong) In any method M attached to a Class C, data can be accessed and messages can be sent to only the following objects: • the arguments of the method M including self • The instance variables defined in the class containing the method being executed. (no direct access to inherited instance variables.) • Global objects • the local objects of M
Law of Demeter (from Dr. Gordon) In any method M attached to a Class C, data can be accessed and messages can be sent to only the following objects: • the arguments of the method M including self • the local objects of M • (no direct access to instance variables.)
Cohesion Revisited • Varieties of Cohesion • Coincidental Cohesion • Logical Cohesion • Temporal Cohesion • Communication Cohesion • Sequential Cohesion • Functional Cohesion • Data Cohesion
Coincidental Cohesion • This cohesion occurs when the components have no apparent reason for being grouped together • In OO framework, we say that it occurs when a class consists of methods that are unrelated • It is usually a sign of poor design in any software design approach.
Logical Cohesion • This occurs when there is a logical connection among the elements of the software but no actual connection • A library of mathematical functions might exhibit logical cohesion
Temporal Cohesion • This occurs when the elements are bound together because they are all used at approximately the same time. • The initialization routines of a compiler or other such software are usually a good example of temporal cohesion. • A better OO approach would be to spread the initialization work over classes that would more closely be charged with subsequent behavior.
Communication Cohesion • This occurs when methods are grouped because they all access the same data or devices. • The “class” acts as a manager for the data or devices.
Sequential Cohesion • This occurs when elements in a class are linked by the necessity to be activated in a particular order. • A better design would be to raise the level of abstraction • Since the sequentiality must be captured at some level, the goal is to hide this as much as possible from other levels of abstraction.
Functional Cohesion • This is a desirable type of cohesion in which the elements of the component all relate to the achievement of a single goal. • The measure of quality design at the level of a method is functional cohesion. • Each method should have a clearly stated unifunctional goal achieved by that method.
Data Cohesion • At the OO level, this is the measure of the quality of design of a class • A class defines a set of data values and exports routines that manipulate the data. • Data Cohesion occurs when a class is designed to implement a data abstraction.
Estimating Cohesion Write a brief statement of the Class (method). • If the statement that describes the purpose of a class (method) is a compound statement containing more that one verb, the class is probably performing more than one function. It probably has sequential or communicating cohesion • If the statement contains words relating to time, it probably has sequential or temporal cohesion. “Wait for ... “ • If the predicate of the statement does not contain a single specific object following the verb, it probably has logical cohesion. “Edit all data” • If the statement contains words such as initialize or clean-up, it is probably temporal cohesion.