Part of the ObjectBasedProgramming pattern language. Discussion occurs on FamilyFusionDiscussion. Original at http://www.geocities.com/SiliconValley/Foothills/5962/familyfusion.htm ---- '''Intent''' Reduce the number of types of instance data structures reducing the complexity of the polymorphic functions and buffer management. '''Motivation''' Subclasses with an common ancestor often share a number of common attributes, while having additional class-specific attributes. To contain the information to instantiate a subclass, a different set of information is required in the instance data. The proliferation of subclasses can therefore lead to a proliferation of instance data structures. This has unfortunate effects on the implementation of the polymorphic functions, as the polymorphic functions must now grapple with the complexities of dealing with multiple instance data structures. Buffer management for the instance data also becomes correspondingly complex. '''Applicability''' Use the FamilyFusion pattern when * Objects are instantiated from multiple concrete subclasses in a class family, and the subclasses share a majority of attributes. * Addition of a new subclass should have minimised impact on existing operations. '''Solution''' The different subclasses in the class family share one common family instance data structure. The family instance data structure contains the aggregate of all attributes appearing in each subclass. The number of instance data structures required for a class family is reduced to one. If the FunctionPointer pattern variation #1 is applied, the operation pointers will also be included in the instance data structure. In which case, the family instance data structure contains the aggregate of the pointers for the polymorphic operations in each subclass. '''Consequences''' The Family Fusion pattern has the following consequences: 1. ''Increased memory use.'' For any instance of a subclass, its instance data may include attributes not required by its class. Hence there is some storage inefficiency. The degree of memory inefficiency depends on the degree of divergence in the attributes of the subclasses. 2. ''Increase in performance and a reduction in code size.'' The polymorphic functions for this class family now deal with one instance data structure. An operation needs only do one type-casting to access the instance data structure. It no longer needs to do different type-casting for different subclasses. An increase in performance and reduction in code size is expected. The resulting code would also be more maintainable. 3. ''The operations are shielded from the addition of new subclasses.'' As the operations work on one instance data structure, as long as the operation behaviour is not overridden, the implementation of the operation needs not be modified for new subclasses. This characteristic improves the maintainability and extensibility. 4. ''Simpler buffer pool management.'' The number of types of instance data structure is greatly reduced. If the instance data structures are allocated from a buffer pool, the buffer pool manager for this class family now has to deal with one type of data structure. '''Sample Code''' Consider the following class hierarchy. The superclass Condition is subclassed into three concrete subclasses. You will observe that the concrete subclasses share a majority of attributes and operations. Although it is possible to use an separate data structure to store the instance information for each concrete subclass, doing so is unwieldy. [1] An example definition of the instance data structures for the three concrete subclasses. The ClassTag pattern is also applied to provide run-time typing information. typedef struct { int nConditionClass, /* class tag */ char abDescription[10], int nChangeCount, int nDescendentChangeCount, BOOL bstate, tsOID sIdentifier } tsSIMPLE_CONDITION; typedef struct { int nConditionClass, /* class tag */ char abDescription[10], int nChangeCount, int nDescendentChangeCount, BOOL bstate, tsOID sIdentifier, int nParentAlarmHandle, /* reference to the parent alarm */ int nNextSiblingAlarmHandle /* reference to the next sibling alarm */ } tsLEAF_ALARM; typedef struct { int nConditionClass, /* class tag */ char abDescription[10], int nChangeCount, int nDescendentChangeCount, BOOL bstate, tsOID sIdentifier, int nParentAlarmHandle, /* reference to the parent alarm */ int nNextSiblingAlarmHandle, /* reference to the next sibling alarm */ int nFirstChildAlarmHandle, /* reference to the first child alarm */ } tsNON_LEAF_ALARM; By applying the family fusion pattern, the three separate data structures are collapsed into one as follows: typedef struct { int nConditionClass, /* class tag */ char abDescription[10], int nChangeCount, int nDescendentChangeCount, BOOL bstate, tsOID sIdentifier, int nParentAlarmHandle, /* used by descendants of alarms only */ int nNextSiblingAlarmHandle, /* used by descendants of alarms only */ int nFirstChildAlarmHandle, /* used by descendants of non-leaf alarms only */ } tsCONDITION; You will notice that three of the fields in tsCONDITION may be empty depending on the class of the instance. The FunctionPointer pattern is not applied in this example. The function pointers are treated the same way as the attributes if the operation pointer had been applied. '''Known Uses''' The Condition Manager in Network Management Unit Software (NUS) developed by MAS Technology applies the FamilyFusion pattern to implement the condition class hierarchy. The example used comes from the Condition Manager. '''Related Patterns''' This pattern provides a strategy to design the instance data introduced by the InstanceData pattern. The FamilySplit pattern provides a different technique to design the instance data structure for a class family. Although the FamilySplit pattern involves higher complexity, it has less storage wastage.