Sunday, July 8, 2012

Delegation Pattern

Android AsyncTask Example

Definition
In software engineering, the delegation pattern is a design pattern in object-oriented programming where an object, instead of performing one of its stated tasks, delegates that task to an associated helper object.
Simple Delegation
Figure 1: simple delegation

Delegation and Inheritance
In languages such as Java, in which multiple inheritance is not supported, delegation can be used to fill in this gap. From this perspective, delegation is like inheritance done manually through object composition.
Delegation and Inheritance
Figure 2: delegation and inheritance

More Than Just Inheritance
By using interfaces, delegation can be made more flexible and typesafe. Flexibility and type-safety here means that the delegator doesn't need to refer to any ClassA or ClassB. As shown by the image below, it can delegate its tasks to any object that implements/conforms to the delegation interface.
Delegation and Interfaces/Protocols
Figure 3: delegation and interfaces(or protocols)
The example below shows how flexibility and type-safety are achieved in delegation pattern by taking advantage of interfaces.
Client

A Use Case - Asynchronous Tasks
Asynchronous tasks run in background. It is vital for a multi-thread program to handle the communication between the background threads and the main thread gracefully. One convenient way of doing so is using delegation pattern where an object, running in the main thread, plays the role of the background operation's delegate, and gets notified of changes in background operation's status such as partial/full completion and errors.
Figure 4: delegation and asynchronous tasks
In the following, a simple Android example of what is discussed above will be explored. This example is created in eclipse IDE on (Source code available for download). The image below shows screenshots of the app in different stages.
Figure 5: sample Android app screenshots
When the "Start Long Operation" button is pressed, a long operation is started in the background. The long operation notifies the main thread of different stages of the task accomplished so that the main thread can update a progress bar to provide feedback to the user. When the long operation ends, the main thread shows a message to the user saying the task is completed.
Class LongOperation that runs in the background:

The main activity that implements the LongOperationDelegate interface and invokes the background operation:
(Source code available for download)

iOS vs. Android - Delegation pattern
This is actually a comparison between Objective-C protocols and Java interfaces. In Obj-C protocols methods can be defined as optional which means objects conforming to the protocol (conforming to a protocol is Obj-C terminology for implementing an interface), may or may not implement those methods.
Figure 6: an Objective-C protocol
Whether an object has implemented a method or not can be determined by the caller object using respondsToSelector method.
Figure 7: caller object uses respondsToSelector method to determine if a method is implemented by other objects
Optional methods facility makes Obj-C protocols very flexible. This is why iOS Cocoa Touch Framework relies on delegation pattern so heavily.

Java Adapter Classes
Java interfaces can be made more flexible using adapter classes. An adapter class is an abstract class that implements an interface. All the methods of the interface are implemented with an empty body or a body that only throws an exception. Other classes that were supposed to implement the interface directly, will extend the adapter class instead overriding only those methods that are needed. In this way objects do not have to implement a lot of empty and useless methods as a result of implementing an interface.
Figure 8: Java adapter classes
Adapter classes are used in Java API as well. The interface MouseInputListener, which includes many methods, comes with MouseInputAdapter which is an abstract class implementing all methods declared in the interface.

2 comments:

  1. Delegation design pattern is used by multiple classes to work collaboratively. Java emphasizes on principal of single responsibility i.e. One class should maintain code only for one specific business responsibility For example An Customer class should be responsible only for managing customer data If it starts managing the customer Orders as well It violates the principal of single responsibility. - See more at:



    http://efectivejava.blogspot.in/2013/08/delegation-design-pattern.html
    http://efectivejava.blogspot.in/2013/08/delegation-design-pattern.html

    ReplyDelete
    Replies
    1. Delegation does not necessarily violate the "single responsibility" rule. For example, you may have a class whose task is lengthy and you want to perform the task in the background to ensure usability won't be at risk. Running a task in background can be handled gracefully using Delegation.
      In another instance, imagine your single-task class provides different sorts of output or triggers different events which then could be easily forwarded to a delegate object, such as that of "tableviews" in iOS.
      Please correct me if didn't get you correctly.

      Delete