This is one pattern in a PatternLanguage (actually, an IdeaLanguage, hence the Form: section) on how to design systems with GemStonej. The language will soon be published in Wiki style. See DataTransferObject, BagOfJumpingBeans. --RandyStafford ---- '''Form:''' Pattern '''Context:''' Youre developing an application using Three-Tier Distributed Object Architecture and Service-Based Architecture. '''Problem:''' How to distribute domain objects (or their state) to remote clients? '''Forces:''' * remote clients of the service layer require access to domain objects, or at least their state information, for display/editing purposes * but distribution of remote references to domain objects may be precluded (e.g., under Multiplexed Sessions and Service-Controlled Transaction), or non-performant (due to a large number of remote invocations being required to accomplish the clients purposes) * and Replicated Domain Object may not be appropriate because the transitive closure of the domain object in question may be too large * and the principle of encapsulation deters us from flattening service-layer method signatures to operate on long parameter lists representing the state of (graphs of) domain objects (MartinFowler's RefactoringImprovingTheDesignOfExistingCode pp.78-79) '''Solution:''' * For each class of domain object that cannot be passed by value, design a unique class of object to hold the state information of that domain object class. * For convenience these classes may specialize a common abstract superclass, e.g., DomainObjectStateHolder. * To support client code purposes that require only the basic identity of the domain object, create an identity holder class. To support client code purposes that require the state of the domain object, create a state holder class extending the identity holder. * Constrain the types of the instance variables of DomainObjectStateHolders to be pass-by-value types (i.e., primitive types, simple types, other DomainObjectStateHolders, or pass-by-value collections of these types). Obeying this constraint ensures that all DomainObjectStateHolders are themselves Pass-By-Value Objects. * DomainObjectStateHolder subclasses should be responsible for appropriately setting their instance variable values given an instance of their corresponding domain object class, and for the converse. * DomainObjectStateHolder classes should also implement the Domain Object Interface '''Rationale:''' Using Domain Object State Holders results in an effective balance of the forces in the context. A specific amount of encapsulated domain object state information, appropriate to the purpose at hand, can be passed by value to the remote client in a single remote invocation. '''Resulting Context and Related Ideas:''' * The development organization must maintain an extra class (hierarchy) for each domain object class that requires a DomainObjectStateHolder. This burden is mitigated by waiting to develop state holder classes until they are first needed (during implementation of the first use case that needs them). * In Java, which is strongly-typed and separates interface from implementation, a further problem arises: that of how to type the domain object classes, their respective state holders, and the client code that uses them. This problem is solved by applying Three Levels Of Domain Object Interface. * Some layer within the systems behavioral boundary must be responsible for initiating Domain Object / State Holder Conversion. * An unexpected benefit of applying Domain Object State Holder is that DomainObjectStateHolders serve as convenient Mementos [Gamma, et.al., Design Patterns, 1995]. ---- I have this generically as StateObject . ---- This looks like the way code is organized in the SelfLanguage, in an odd, reversed sort of way. In Self, the state object sits at the front, but if you try to do some operation on it it appeals to its parent (the traits object) where you would store the code common to all of the objects in that 'class' (self is classless but its a near analogy). In self, cloning is fundamental, and it strikes me that it is a desire to clone objects that leads to this pattern too.