Encapsulation Patterns
Patterns That Provide Forms of Encapsulation
Sometimes you want to encapsulate a group of classes in order to
implement an abstract view of their combined functionality.
Often when this is done you may still want to be able to be able to
access the classes directly.
-
Facade - provides a unified interface to a
set of interfaces in a subsystem making it easier to use.
Examples: JTable, JTree, JEditorPane.
Sometimes you just want to define an abstract behavior that has several
variations.
That is, you want to encapsulate several algorithms that share a common
interface to make them interchangeable.
-
Strategy - defines a family of algorithms,
encapsulate each one, and make them interchangeable.
Strategy lets the algorithm vary independently from clients that use
it.
Examples: Swing layout managers.
Patterns That "Violate" Encapsulation
Sometimes you need to "violate" encaplsulation at a low level in order to
do a better job of encapsulation at a higher level.
Although this sounds contradictory, the improvement arises from the fact
that allowing higher level classes to directly access data in lower level
classes or vice-versa avoids having to declare public methods for the
access.
For this reason, well-designed OOLs have mechanisms that allow one class
to have access to private members of another class.
In C++, for example, you can declare one class as a "friend" of another
class.
In Java, a class can be nested inside of another class, which allows
both classes to access private members of the other class.
-
Observer - often provides a public method
for modifying an object that it has private access to, but another
object (a Subject) decides when the modification will occur.
Example: Swing listeners.
-
Iterator - provides access to objects in an
Aggregate without exposing the implementation of the Aggregate.
Examples: java.util.Iterator objects for java.util.Collection classes.
-
Memento - carries state information about
an Originator object, allowing the Originator private access to that
information.
In most cases a Memento has no public interface at all.
Clients can get a Momento from an Originator but the only thing they
can do with it is pass it as a parameter in a message sent to the
Originator.
Example: often used to support "undoable" operations in editors.