hosted by Sourceforge
At the heart of the current application are two patterns. The Composition pattern and the Prototype pattern. These are thoroughly described in ‘Design Patterns – elements of reusable object-oriented software’. I have provided a short description of each which describes their implementation in the framework.
Within the application the prototype pattern is used for a few, key purposes. The pattern reduces the need for sub-classing. Part instances are one example. One part, in terms of its structure, is pretty much like another. It is the elements of that structure that are different. The prototype patterns permits the construction of template instances. These instances can then be cloned and modified by the application or the end-user. Take a hard disk drive. Rather than creating a distinct class representing this device, a prototypical drive instance is created. When a new hard drive is required the prototypical instance can be cloned and edited.
A second advantage is that the prototype patterns works very well in conjunction with the composition pattern. A composition node can be cloned, maintaining the structure of all its children, and it’s children’s children with little coding effort.
The implementation is based on the jcengine.core.Prototype interface. The interface provides an override to java.lang.Object in the form of the clone method. This method is implemented in all the classes as public. This implementation is worthy of debate since many developers recommend creating a differently named clone method. However, I currently think that since casting is required in either case it is irrelevant.
The second point to note is that I have not provided a copy constructor. This is specified in the Prototype pattern but because the classes are still under development and may well change it is not implemented.
The third point is that in all the concrete classes, calling the clone method provides the clone with a unique key. In the original state this key is null. This was to permit easy identification between prototypical and cloned instances.
The composition pattern is a commonly used and effective pattern that permits instances to participate in parent-child relationships. There are two basic types of instance: node and leaf. Nodes can potentially have children whereas leafs are essentially childless and represent the terminus of a branch. The composition pattern represents an excellent mechanism for demonstrating a hierarchical structure between instances. It also lends itself nicely to using Java’s default serialization or XML.
This pattern is encapsulated in the interface jcengine.core.Compositor. It closely follows the recommendations provided in 'Design Patterns – Elements of Reusable Object-Oriented Software’. There are some points of note.
Providing a parent reference is supported by a custom implementation of a java.util.List. This implementation differs from the original in that it automatically adds a parent reference to any Compositor based instance that is added. The framework also provides mediators that notify listeners of any modifications (this will be covered more thoroughly in a different section).
Node and leaf instances share a common interface. However they vary in implementation. A leaf instance will not possess any further composition. The main validation of the type of instance is done via the getComposition method. This method returns a null if the instance is a leaf or a reference to itself if the instance is a node. In the framework there are four abstract implementations of the Compositor interface: AbstractLeaf, AbstractNode, AbstractVisualLeaf, AbstractVisualNode. Nodes in both cases are subclasses of the abstract leaf classes.
Back to main
Java is a registered trademark of Sun Microsystems, Inc. Windows 95 and Windows NT are trademarks of Microsoft Corporation. All other product names and company names mentioned herein are the property of their respective owners.