Define the notation for specifying delegation, an alternative to inheritance.
Specifying UML Delegation as an Alternative to Inheritance
Generalization tends to be overused, much like aggregation. Remember that generalization does generate different code, so be sure that you are using it properly. Some design pattern texts use alternatives to generalization that provide more control.
Specifying Delegation is an alternative to inheritance in UML
In Unified Modeling Language (UML), delegation is an alternative to inheritance as a way of reusing behavior and functionality across classes. While inheritance is a popular method of modeling relationships between classes through parent-child relationships, delegation relies on forwarding requests from one object to another to reuse behavior.
Delegation is a technique where an object, instead of performing a task itself, delegates or forwards the responsibility to another object, known as the delegate. This allows for behavior and functionality to be shared between classes without inheriting from a common superclass.
In UML, delegation can be represented using collaboration, which is a way to show how objects interact to fulfill a particular task or behavior. UML provides several notations for representing delegation, including:
Dependency relationship with stereotype <<delegate>>: This is the most explicit notation for showing delegation in UML. A dashed arrow with the stereotype <<delegate>> indicates that one class delegates a specific responsibility to another class. The arrow points from the delegating class to the delegate class.
Association relationship: An association is a solid line connecting two classes, indicating that one class has a reference to an instance of another class. In the context of delegation, the association can be used to represent the relationship between the delegating class and the delegate class. The delegating class holds a reference to the delegate class and forwards the requests accordingly.
Aggregation or composition relationship: In some cases, delegation may be modeled as a part-whole relationship between the delegating class and the delegate class. This can be represented using aggregation (an empty diamond at the whole end) or composition (a filled diamond at the whole end). These relationships indicate that the delegating class consists of or is composed of the delegate class.
In summary, delegation in UML is an alternative to inheritance for sharing behavior and functionality across classes. It can be represented using different notations, such as dependency relationships with <<delegate>> stereotype, association relationships, or aggregation/composition relationships. By using delegation, you can create more flexible and modular designs, avoiding some of the pitfalls associated with deep inheritance hierarchies.
The delegation technique makes one class a part of another class, using aggregation. When the containing class requires assistance it simply forwards, or delegates, the request to the component class. When the component class is finished with the delegated task it returns control to the requestor.
Delegation is a common technique for allowing one class to get help from another class without using inheritance.
To give one class access to another, follow these steps described below in the series of images:
Identify the class that needs help. A TextBox needs to be drawn in a variety of shapes.
Identify the class with the desired behaviors; a Shape superclass with sub-classes like Ellipse and Polygon, and a predefined shape called Cloud.
To use these shapes, tell the TextBox about them using aggregation. Remember to assign the multiplicity at each end
Implement the aggregation association using a new attribute in TextBox called boxshape. The data type of boxshape is Shape, the class that is associated with TextBox.
Implement the draw() operation in the TextBox by delegating the operation to the Shape object in the boxshape attribute.
UML Delegation TextBox
A Delegate connector defines the internal assembly of a component's external Ports and Interfaces, on a Component diagram. Using a Delegate connector wires the internal workings of the system to the outside world, by a delegation of the connections of external interfaces.
A connector between an external port of a structured classifier or component and
an internal part. Connections to the external port are treated as going to the element
at the other end of the delegation connector.
In object-oriented languages, delegation is a technique that enables objects to handle a request by delegating operations to its delegate.
In most of OO programming languages, delegation is realized as object composition, keeping a reference to a delegated object in the delegating object. To accomplish a task, the delegating object invokes operations in the delegated object. Delegation is an alternative to inheritance. The delegating object can contain common behaviors, while the delegated objects support variant behaviors. Once the delegating object receives a request it cannot satisfy, it forwards the request to corresponding delegated objects. Delegation is widely used in many design patterns to handle variability. Examples of these patterns include the State, Strategy, and Visitor patterns. Wrapping can be also considered as a special use of delegation. Like x-frames, the delegating objects contain reusable knowledge and are extensible. The difference is that delegation composes behaviors at runtime, whereas XVCL supports
adaptation and composition at program construction time. Being a runtime mechanism, delegation makes software more flexible. However, when the number of variants increases, especially when the interdependencies of the variants are considered, the
number of required delegated and delegating objects may grow quickly. There are also runtime inefficiencies with delegation.
For another application of the delegation technique, look at the
State design pattern.
This pattern can be very helpful in an application that requires complex state behavior. The next lesson concludes this module.