package com.orbs.ref.pattern.conservator; import java.io.Serializable; import java.util.Vector; /********************************************************************* *
* A Conservator is a singleton registry for Flyweight objects * that prevents the existence of more than one Flyweight object with * the same intrinsic state. *
* Flyweight objects, implementing the interface to only the Intrinsic * state accessor and mutator methods, are contained by Heavyweight * objects as shared delegates. A Heavyweight object implements the * interfaces for both the Extrinsic and the Intrinsic state and * simply passes along any intrinsic state accessor method calls to its * shared flyweight delegate. *
* However, whenever an intrinsic state mutator method is called upon * the Heavyweight object, it clones its Flyweight delegate and calls * the mutator method on the clone instead. The mutated clone is * then passed to the Conservator via the conserve() method and the * Heavyweight's old Flyweight delegate is replaced with the returned * Flyweight. *
* The conserve() method simply checks that the values of the * mutated Flyweight clone that was passed to it are unique. If they * are not, the Flyweight object that was previously registered with * those values in the registry is returned instead. The Heavyweight * accepts this older object to be shared as a delegate with other * Heavyweight objects. In this case, the newly created but redundant * Flyweight is dereferenced in the process of reassigning the * Heavyweight's delegate to the older and first Flyweight with that * same intrinsic state; the redundant Flyweight object is eligible * for garbage collection and will eventually be destroyed. *
* In the case that the mutated Flyweight clone does have a unique set * of values, the clone is registered with the Conservator for future * use by other Heavyweight objects and returned directly to the * creating Heavyweight object. *
* Note that there is a problem with garbage collection in that * the Conservator maintains a cache of Flyweight objects even * after all of the Heavyweight objects that referenced them may have * been destroyed. A future implementation of the Conservator * class is likely to utilize the new language feature described as * "weak references" in Java 1.2 when it is released. *
* References *
*
* Design Patterns: Elements of Reusable Object-Oriented Software
*
* 1995; Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides
*
* Conservator extends on the concept of a Flyweight Factory by * allowing shared Flyweight objects to be mutated after creation * without undesired side effects. *
* @author * David W. Croft * @version * 1998-04-19 *********************************************************************/ public class Conservator implements Serializable ////////////////////////////////////////////////////////////////////// // Serializable just in case you want to save it. ////////////////////////////////////////////////////////////////////// { private Vector vector = new Vector ( ); ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// public synchronized Object conserve ( Object clone ) ////////////////////////////////////////////////////////////////////// // The indexOf() operation works by calling the equals() method // of the compared objects. So long as the objects override their // equals() method to return true if the objects share the same // class and instance values, this method will work. See the source // code for java.lang.String.equals() as an example. // // Synchronized for your protection. ////////////////////////////////////////////////////////////////////// { int index = vector.indexOf ( clone ); if ( index > -1 ) return vector.elementAt ( index ); vector.addElement ( clone ); return clone; } ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// }