Amazon.com Widgets An Interface Implementation Pattern for Consideration

An Interface Implementation Pattern for Consideration

By Nick at February 03, 2012 14:42
Filed Under: Delphi, Software Development

So I’ve been writing about Interfaces, and mostly talking about how you should use them.  But as important as designing and using the interfaces themselves is how you implement those interfaces.  I talked about the basics in the previous article, but there are some things that you can do to make implementing an interface a little easier.

I’d like to show one way that you might go about it for the purpose of starting a discussion about the technique.  I’ve seen the method I’m going to describe below used in a number of places, most notably back in WebSnap. (Remember that?  WebSnap was actually a pretty cool library of code, doing a lot of things in a somewhat MVC fashion  before MVC and web development was in, well, fashion.)

Anyway, here is how the implementation pattern I’m talking about here works:  You create a “base” class that implements each member and property of the interface. Then, you add a virtual, abstract method that corresponds to each interface method with a naming convention of DoMethod.  You then call that virtual, abstract method inside the implementation of the interface methods. 

This base class then becomes the parent for any class that implements the interface.  In essence, you create an easy-to-inherit class that easy implements the interface so you don’t actually have to worry about implementing the interface over and over again. 

Naturally, this is hard to explain, so a code example is in order.

Consider the following simple interface:

type
  IDemoInterface = interface
    procedure ProcessSomething;
    function ProcessData(aString: string; aInteger: integer): Boolean;  
  end;

Nothing fancy, and obviously illustrative. 

To do what I’m talking about, you’d implement this interface as follows:

type

  TBaseDemoInterfaceImplementor = class abstract(TInterfacedObject, IDemoInterface)
  protected
    procedure DoProcessSomething; virtual; abstract;
    function DoProcessData(aString: string; aInteger: integer): Boolean; virtual; abstract;
  public
    procedure ProcessSomething;
    function ProcessData(aString: string; aInteger: integer): Boolean;
  end;

procedure TBaseDemoInterfaceImplementor .ProcessSomething;
begin
  DoProcessSomething;
end;

function TBaseDemoInterfaceImplementor .ProcessData(aString: string; aInteger: integer): Boolean;
begin
  Result := DoProcessData(aString, aInteger);
end;

So, what you have now is a class – TBaseDemoInterfaceImplementor – that can be used to really implement the functionality of the IDemoInterface.  You have an abstract class to inherit from, and two methods to override to implement the functionality. 

So, of course, the class that you’ll actually use would look something like this:

type
  TRealDemoInterfaceImplementor = class(TBaseDemoInterfaceImplementor)
  protected
    procedure DoProcessSomething; override;
    function DoProcessData(aString: string; aInteger: integer): Boolean; override;
  end;

function TRealDemoInterfaceImplementor.DoProcessData(aString: string; aInteger: integer): Boolean;
begin
  ShowMessage(Format('I am processing the following data: %s and %d', [aString, aInteger]));
  Result := Random(2) = 1;
end;

procedure TRealDemoInterfaceImplementor.DoProcessSomething;
begin
  ShowMessage('I am processing something!');
end;

What happens is that the implementation becomes much less painful once you have the base class defined with the details of implementing the interface neatly tucked away.  You are doing simple class inheritance at that point. 

Now I’ve thought about this pattern for a while, but I’m not sure about it.  I’m very interested in hearing what you all think.  I guess one downside is that the class doesn’t clearly declare that it implements a given interface.  Perhaps a naming convention would do that? 

On the one hand, it seems a nice way to create a class library that implements an interface.  To me, it seems like a good use of polymorphism. There may be times when you want a large chunk of your library to implement a “basic” interface, and using this inheritance trick can make that easy.  Once you create a base class, you can now build a class hierarchy based on that class, with all the classes implementing the interface with much less hassle and more cleanly.  In addition, it makes it easier to create any number of descendants  from the base class if you want to have a number of different implementations for the interface.  For instance, if you had ICreditCard, you might create TBaseCreditCardImplementor, making it easy to descend from and create TVisa and TMastercard, etc. 

Pattern? Anti-pattern?  Maybe I’m crazy and this is a really silly idea.  Maybe this is a known pattern already and I’m just ignorant.  Maybe this is the coolest idea ever. 

What do you guys think?

blog comments powered by Disqus

My Book

A Pithy Quote for You

"You cannot increase the water in a swimming pool by taking water from the deep end and pouring it into the shallow end."    –  Me

Amazon Gift Cards

General Disclaimer

The views I express here are entirely my own and not necessarily those of any other rational person or organization.  However, I strongly recommend that you agree with pretty much everything I say because, well, I'm right.  Most of the time. Except when I'm not, in which case, you shouldn't agree with me.