.NET Design Patterns: The Delegation Pattern

Pattern Type: Composite

Intent

The intent of the delegation pattern is simply to pass off the delegation of an operation to a different class. In many cases, this "final class" would be hooked up at compile time; however, there are a number of cases where the delegation pattern can be used to dynamically change the final destination at run time.

However it's used, the intention is for the method being called not be the method that actually handles the request.

Description

The delegation pattern is in itself a very simple pattern. Generally, you'll mirror the input data from the called method into an identically typed method signature.

If you don't pass the called method off on to an identically typed method signature, you're using the "Adapter Pattern" or maybe a derivative of the "Bridge Pattern," both of which change the method signature called.

One place where you'll very often find the delegation pattern used is in Async-based operations. For example, you may call a method to "Download A File," and that method may fire off a "Task" that returns when the download has finished.

Your simple download method, to the consuming code, just looks like a simple call that returns a string. Behind the scenes, however, that simple function spins off a thread or Async call whose actual call is masked by the called method.

Diagram

Delegate1
Figure 1: Single- and double-instance Caller diagram

Description of diagram elements:

  • Caller: This is the consumer making a call to the requested method.
  • SomeMethod: This is a concrete implementation of the method being called in the enclosing class.
  • FinalMethod: This is the concrete implementation of the method being called from the SomeMethod parent; this is the delegated action.
  • IDelegationInterface: This is an interface, defining the appearance of a class containing a final method as a concrete implementation, allowing the final implementation to be changed.

Implementation in C#

To produce a single instance Delegation, you simply need a calling application, and two concrete class implementations.

namespace NutsAndBolts
{
   class Program
   {
      private static DelegationClass _delegationClass
         = new DelegationClass();

      static void Main()
      {
         _delegationClass.SomeMethod(1, 2, 3);
      }
   }
}

Code for the caller

namespace NutsAndBolts
{
   class DelegationClass
   {
      private readonly FinalClass _finalClass =
         new FinalClass();

      public void SomeMethod(int a, int b, int c)
      {
         _finalClass.FinalMethod(a, b, c);
      }

   }
}

Class representing our delegation

using System;

namespace NutsAndBolts
{
   public class FinalClass
   {
      public void FinalMethod(int a, int b, int c)
      {
         Console.WriteLine("Final method called in
            the delegation chain.");
      }
   }
}

Class representing our final concrete implementation

Implementing a multiple call is not much different, except that our delegation class derives from an interface, rather than from a concrete object. Because an interface is used, the implementation to call can, if desired, be changed at run time.

namespace NutsAndBolts
{
   public interface IDelegationInterface
   {
      void FinalMethod(int a, int b, int c);
   }
}

Delegation interface

Then, we simply create our final classes to derive from this interface, and modify the delegate caller as required.

namespace NutsAndBolts
{
   class DelegationClass
   {
      private readonly IDelegationInterface
         _finalClass;

      public void SomeMethod(int a, int b, int c)
      {
         _finalClass = new FinalClass();
         // or
         _finalClass = new FinalClass2();

         _finalClass.FinalMethod(a, b, c);
      }

   }
}

Updated Delegation Class

using System;

namespace NutsAndBolts
{
   public class FinalClass: IDelegationInterface
   {
      public void FinalMethod(int a, int b, int c)
      {
         Console.WriteLine("Final method called in
            the delegation chain.");
      }
   }
}

Updated final class implementation

using System;

namespace NutsAndBolts
{
   public class FinalClass2: IDelegationInterface
   {
      public void FinalMethod(int a, int b, int c)
      {
         Console.WriteLine("Final method 2 called
            in the delegation chain.");
      }
   }
}

Final class 2 concrete implementation



About the Author

Peter Shaw

As an early adopter of IT back in the late 1970s to early 1980s, I started out with a humble little 1KB Sinclair ZX81 home computer. Within a very short space of time, this small 1KB machine became a 16KB Tandy TRS-80, followed by an Acorn Electron and, eventually, after going through many other different machines, a 4MB, ARM-powered Acorn A5000. After leaving school and getting involved with DOS-based PCs, I went on to train in many different disciplines in the computer networking and communications industries. After returning to university in the mid-1990s and gaining a Bachelor of Science in Computing for Industry, I now run my own consulting business in the northeast of England called Digital Solutions Computer Software, Ltd. I advise clients at both a hardware and software level in many different IT disciplines, covering a wide range of domain-specific knowledge—from mobile communications and networks right through to geographic information systems and banking and finance.

Related Articles

Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date