Design Patterns 1: Requested Change
Design Patterns 1: Requested Change
1. computing results
2. study for the exam.
Solution: Add 2 new methods that implement the 2 behaviors, in the superclass.
Problems arrised:
− not all teachers compute the result with the same formula;
− Sports is facultative and have no result;
− there are different ways to study for SwEng and English; also Sports needs no computer
assisted study.
General problem: Client will periodically request changes in the behavior of a product.
Solution: Use interfaces.
The operations result() and study() from Course where transferred to interfaces Result
and Study respectively.
Problems:
− code structure is disrupted;
− behavior is still implemeted in subclasses.
P1 (GOOD OO DESIGN PRACTICE 1): Identify the aspects of the application that vary and separate them
from what stays the same.
Procedure:
− take the parts that vary;
− encapsulate them;
− independently alter and/or extend them later.
Applying P1 to our example: separate result() and study() operations in 2 classes, Result
and Study, that contain all needed implementations.
Subclasses of Course can instantiate objects of type Result and Study, on which to call
correspondent methods. We say the Course delegates behavior to Result and Study classes.
Obs. The base class (Course) is still a superclass for SwEng, English, Sports (and other
possible subclasses).
P2 (GOOD OO DESIGN PRACTICE 2): Program to an interface (more generally: to a supertype), not to an
implementation.
Advantages:
- other types of objects can reuse these behaviors
- new behaviors can be added without affecting:
- any existing behavior
- any class that use existing behavior
Applying P2 to our example: consider interfaces Result and Study which represent changing
behaviors. Specific implementations from SwEngResult, EnglResult, SwEngStudy and
EnglStudy are used at runtime based on polymorphism.
Recommendations:
1. Principles and patterns can be applied at any stage of the development lifecycle.
2. Keep commonalities in a base superclass (does not need to be an interface). The base
superclass delegates changing behavior to specific interfaces.
IMPLEMENTATION:
a. In the base class add instance variables declared of interface behavior type.
b. Remove from the base class and its subclasses all methods associated previously with the
considered behavior.
c. In the base class add methods that perform behavior.
d. To set statically the behaviors: set values for behavior instance variables in subclasses
constructors.
e. To set dynamically the behaviors: set values for behavior instance variables in a dedicated
method in subclasses.
Class Course delegates specific behavior to the objects referenced by resultB and studyB
instance variables.
The instance variables resultB and studyB are inherited from Course.
The method performResult() inherited from Course will realize, by polymorphism, the
behavior implemented in SwEngResult.
- add setter methods for resultB and studyB instance variables in the base class:
For testing:
- we suppose that a new way to compute results for Software Engineering is added, implemented
in:
Name:
STRATEGY (POLICY)
Intent:
Design a family of algorithms, encapsulate each one, and make them interchangeable.
STRATEGY lets the algorithm vary independently from clients that use it.
Structure:
Participants:
Strategy:
- declares an interface common to all supported algorithms;
- Context uses this interface to call the algorithm defined by a ConcreteStrategy.
ConcreteStrategy:
- implements the algorithm using the Strategy interface.
Context:
- is configured with a ConcreteStrategy object
- maintains a reference to a Strategy object
- may define an interface that lets Strategy acces its data.
Aplicability when:
- many related classes differ only in their behavior - Strategy provides a way to configure a
class with one of many behaviors.
- you need different variants of an algorithm - Strategy can be used when these variants are
implemented as a class hierarchy of algorithms.
- an algorithm uses data that clients should not know about – Strategy is used to avoid
exposing complex, algorithm-specific data structures.
- a class defines many behaviors, and these appear as multiple conditional statements in its
operations – instead of many conditionals, move related conditional branches into their own
Strategy class.