Steve Windom has graciously shared the following article on Class Delegation.
We’ve previously touched upon this subject under Class Composition and Function Pointers articles, but Steve’s article provides a coherent and clear view.
Intent: In some situations, using inheritance to extend a class leads to a bad design. Though less convenient, delegation is a more general-purpose way to extend classes. Delegation works well in many situations where inheritance does not work well. For the purposes of test automation, delegation can be a critical technique because some test automation tools, like QTP do not support inheritance.
Context: Inheritance is a common way of extending and reusing the functionality of a class. Delegation is a more general way to extend a classes behavior. Delegation extends a class by using another classes functions, subroutines, and properties rather than inheriting them. Inheritance is inappropriate for many situations in which delegation works well.
For example, inheritance is useful for capturing a “is-a-kind-of” relationships because of their very static nature. However, “is-a-role-played-by” relationships are akward to model with inheritance. With delegation you get instances of classes that can play multiple roles.
Applicability:
- Pro - Inheritance is a static relationship; it does not change over time. If you find that an object needs to be a different subclass of a class at different times, then it should not be a subclass of that class in the first place. If an object is created as an instance of a class, it will always be an instance of that class. However, an object can delegate behavior to different objects at different times.
- Pro - Much or even most reuse and extension of a class is not appropriately done through inheritance.
- Pro - The behavior a class inherits form is base class cannot easily be changed over time. Inheritance is not useful when the behavior a class should build on is not determined until run time.
- Pro – Inheritance is not supported by some test automation tools such as QTP, so delegation is the only viable option to inheritance.
- Con - Delegation imposes less structure on classes than inheritance. In designs where it is important to constrain the structure of classes, the structure and inflexibility of inheritance may be a virtue. This is often the case in frameworks.
- Con - Delegation can be less convenient than inheritance because it requires more code to implement.
Implementation: VBScript as a language does not provide any mechanism for inheritance or polymorphism. However, delegation allows us to fake it. We do this by creating an instance of a theoretical parent class or (the Delegator) within the original class (the Delegatee) and calling its methods. We then call the parent classes functionality in the “inherited” child classes methods which simply call (or delegate to) the same method of the parent class.
Delegation is a more general purpose approach than inheritance. Any extension to a class that can be accomplished by inheritance can also be accomplished by delegation.
Here is a code example: (Note: The examples and code presented in this document are QTP/VBScript examples.)
<span style="color: #0000ff;">Public</span> <span style="color: #0000ff;">Function</span> cDelegator()
<span style="color: #0000ff;">Set</span> cDelegator = New Delegator
<span style="color: #0000ff;">End</span> <span style="color: #0000ff;">Function</span>
<span style="color: #0000ff;">Class</span> Delegator
<span style="color: #0000ff;">Public</span> <span style="color: #0000ff;">Sub</span> SayHello()
<span style="color: #0000ff;">MsgBox</span>("<span style="color: #8b0000;">Hello There!</span>")
<span style="color: #0000ff;">End</span> <span style="color: #0000ff;">Sub</span>
<span style="color: #0000ff;">End</span> <span style="color: #0000ff;">Class</span>
<span style="color: #0000ff;">Class</span> Delegatee
<span style="color: #0000ff;">Dim</span> cDelegator
<span style="color: #0000ff;">Private</span> <span style="color: #0000ff;">Sub</span> Class_Initialize
<span style="color: #0000ff;">Set</span> mDelegator = cDelegator()
<span style="color: #0000ff;">End</span> <span style="color: #0000ff;">Sub</span>
<span style="color: #0000ff;">Public</span> <span style="color: #0000ff;">Sub</span> SayHello()
mDelegator.SayHello()
<span style="color: #0000ff;">End</span> <span style="color: #0000ff;">Sub</span>
<span style="color: #0000ff;">End</span> <span style="color: #0000ff;">Class</span>
As you can see, the SayHello() method in the Delegatee class really uses an instance of the Delegator Class to implement it’s SayHello() functionality.
Consequences: Delegation can be used without the problems that accompany inheritance. Another advancage of delegation is that it is easy to compose behavior at run time.
The main disadvantage of delegation is that it is less structured than inheritance. Relationships between classes built using delegation are less obvious than those built using inheritance. Here are some strategies for improving the clarity of delegation based relationships.
- Use consistent naming schemes to refer to objects in a particular role. For example, if multiple classes delegate the creation of widget objects, the role of the delegatee object becomes more obvious of al the classes that delegate that operation refer to delegatee objects through a variable called widgetFactory.
- Clarify the purpose of a delegation by writing comments.
- In extreme cases, these indirect delegations can make an intermediate class less coherent by adding functions, subroutines, or properties unrelated to the class’s purpose. In such cases, refactor the unrelated functions, subroutines, or properties into a separate class.
- Use well-known design and coding patterns. A person reading code that uses delegation will be more likely to understand the role that objects play if the roles are part of a well-known pattern or a pattern that recurs frequently in your program.
Note: It is possible and advantageous to use all three of these strategies at the same time when you can.
References:
- Mark Grand, Brad Merrill (2005). Visual Basic Design Patterns: Wiley Publishing, Inc.
- Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides (1995). Design Patterns Elements of Object-Oriented Software: Addison-Wesley.



Recent Comments