43 DesignPatterns-Part3
43 DesignPatterns-Part3
Any application class can declare itself to be a subclass of the <<Observable>> class.
In Java, we call these ‘listeners.’
delegatingMethod()
«Delegator» «Delegate» {
delegate.method();
delegatingMethod method }
Create a method in a Delegator class that only calls a method in a neighboring Delegate class.
In this way, we are reusing the method for which Delegate has responsibility, and not developing
our own version.
By neighboring class, we mean that the Delegate has an association with the Delegator class.
Here we can see that Stack operations push, pop, and isEmpty can readily use
existing methods from Linked List class – addFirst, removeFirst, and isEmpty.
• Context:
—You are building an inheritance hierarchy and want to
incorporate it into an existing class.
—The reused class is also often already part of its own
inheritance hierarchy.
• Problem:
—How to obtain the power of polymorphism when reusing a
class whose methods
- have the same function
- but not the same signature
as the other methods in the hierarchy?
• Forces:
—You do not have access to multiple inheritance or you do not
want to use it.
«Adapter» «Adaptee»
adaptedMethod
We don’t want to directly incorporate the reused class into our inheritance hierarchy.
Better: Use an <<Adapter>> class that is connected via association to the reused class. (Adaptee)
Adapters are sometimes called Wrappers. Java wrapper classes Integer, Float, Double, etc
are adapters for the Java primitive types.
* * «Proxy» «HeavyWeight»
«Client»
Create a simpler version of the heavyweight class, which we call a Proxy, which has the same
interface as the heavyweight class so programmers can declare variables without caring about whether
the Proxy or its Heavyweight version will be put in the variable.
The Proxy object is really only a placeholder, and the operations in the Proxy delegate the operation to
the HeavyWeight.
If/when needed, the Proxy can obtain the real heavyweight object. Further, the proxy only needs to
obtain the heavyweight one time and thus make it available in memory to others who use the proxy.
Some proxies may have implementations of a limited number of operations that can be
performed without the effort of loading the Heavyweight object.
«interface»
Student
StudentProxy PersistentStudent
Here we have a variable that is to contain a List. This variable would, however, actually contain a
ListProxy, since it would be expensive to load an entire list of objects into memory, and the list might
not actually be needed. However, as soon as an operation accesses the list, the ListProxy might at
that point create an instance of PersistentList.
On the other hand, the ListProxy might be able to answer certain queries, such as the number of
elements in the list, without going to the effort of loading the PersistentList.
Imagine that the PersistentList is actually a list of students. These objects might also be
proxies – in this case, instances of StudentProxy. Again, instances of PersistentStudent
would only be loaded when necessary.