Amazon.com Widgets An Interface Implementation Pattern for Consideration

An Interface Implementation Pattern for Consideration

By Nick at February 03, 2012 23: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?

Comments (19) -

2/4/2012 12:34:15 AM #

Moz

I'm feeling kinda stupid having read that and still wondering what problem you're trying to solve. Is this one of your leading articles where you're going to come in later and say "voila, here's the real issue I have that made me wonder about this as a solution?"

Right now it just looks as though you're saving yourself 12 characters in a class declaration, at the expense of a whole new class and needing a coding convention to say "this implements an interface". Plus you have the vulnerability of some code monkey coming along later and reintroducing ProcessSomething. Somewhere in my feed is a really good blog post about evaluating programmer productivity by the maintenance overhead introduced, something I'm very aware of having been writing multithreaded code for a while and also working with other people's DIY OPFs. No point writing something really smart if it is write-only code.

I think it's clearer to have the explicit declaration. Especially when you are fulfilling more than one interface. TRealDemoEncryptedCreditCardInterfaceImplementor is starting to get a bit ugly, where TDemoCreditCardE = class (TObject, IEncrypted, ICreditCard, IDemo) is manageable (I prefer postfix hungarian because the alpha sorting works better).

I can see this being implicit if you have a few root classes that implement core interfaces (like TInterfacedObject did in older Delphi versions), or where you have a set of common behaviours across a bunch of classes - IPersistable for example, or IEncrypted. I could see an entire layer having a common interface, for example - all the network-accessible objects implementing a SOAP helper for example.

Is that even vaguely what you're suggesting?

Moz Principality of Monaco |

2/4/2012 12:40:34 AM #

Alex

I don't get the idea behind separate DoXYZ methods. What's the point here?

You can as well declare ProcessSomething and ProcessData as virtual. Then you can override them in TRealDemoInterfaceImplementor and this will work in the same way.

Alex Russia |

2/4/2012 1:19:03 AM #

Serg

Antipattern. You are just implementing an abstract class using interface. If you need an abstract class, use abstract class. If you need an interface, use interface.

Serg Russia |

2/4/2012 3:24:17 AM #

Colin

Hi Nick, I think the pattern that you are describing here is the template method design pattern from the GOF patterns book (http://en.wikipedia.org/wiki/Template_pattern).

@Alex, the example provided by Nick may have been a bit too simplistic. There may not be too much value from a one-to-one relationship between the public ProcessSomething method and the protected DoProcessSomething method but there may be more value if the ProcessSomething method is used to enforce some step-by-step process within itself using several internal primitive operations. For example, based on Nick's interface:

type

  TBaseDemoInterfaceImplementor = class abstract(TInterfacedObject, IDemoInterface)
  protected
    function FirstProcessValid: Boolean; virtual; abstract;
    procedure DoFirstProcess; virtual; abstract;
    procedure DoSecondProcess; virtual; abstract;
    procedure DoThirdProcess; 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
  DoFirstProcess;

  if FirstProcessValid then
    DoSecondProcess
  else
    DoThirdProcess;
end;

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

In this case, subclasses must adhere to steps as defined by the public ProcessSomething method but has control over how the primitive steps get implemented.

I think the value of interfaces are not as apparent when you look at a single interface in isolation but is much more clearer when you see several interfaces used in collaboration. It's when you see the relationship/interaction between interfaces that you then have a better understanding of the roles that each interface plays within the model/framework that they are used in.

Colin Australia |

2/4/2012 12:05:18 PM #

Nick Hodges

Colin --  Excellent comment.  Thanks for expanding and explaining better than I did.

Nick Hodges United States |

2/5/2012 3:14:03 AM #

Paul

You have done a perfect illustration : )

Paul United States |

2/7/2012 9:34:17 AM #

Guido Vezzoni

I agree: most of the time I need an interface, I think about the implementations I need and those one I might need in future: problem is how to avoid duplicated code and most of the time the template pattern in TBaseDemoInterfaceImplementor solves it.

Guido Vezzoni United Kingdom |

2/4/2012 5:13:02 AM #

Georg Stegmüller

I have a maybe naive question: If all classes, which implement a certain interface descend from a single base class, why do I need the interface at all? I could simply use the (abstract) base class?

Isn't the main reason to use interfaces to be able to use common functionality in classes which do not share a common ancestor?

Georg Stegmüller Austria |

2/4/2012 6:18:06 AM #

Daniele Teti

IMHO this is not an anti-pattern. It is simply a way to dont rewerite the same code many times. I've used this "BaseImplementor" over and over again in many part of my code. If you need a completely new interface implementation, you can simply implement the raw interface, but, if you need to change only some part of an interface implementation, then you can inherit from the baseimplementor. This way-to-do-things has been used in dorm (The Delphi ORM) in many part. Specially in the adapter and loggers part. If some interface implementato have an equal implementation for method "xyz" then, I usually do a baseimplementato for that brach of implementors, and all of them inherit from that base. It is simply OOP inheritance applied to a class that have to implement an interface.
Sayd that, I'm not agree with the "Something" and "DoSomething". What is that separation for? (The already exposed reason, is not convincing me... that is a simply template method).

Daniele Teti Italy |

2/7/2012 6:48:04 AM #

baka0815

But than you wouldn't declare all those methods abstract.

What you mean is what Java does with the default-implementations of some interfaces like TableModel - there is a DefaultTableModel which implements all methods from the interface and provides some basic functionality.

baka0815 Germany |

2/7/2012 11:47:53 AM #

baka0815

Where did my comment go? Nonetheless, I try again:

But than you wouldn't declare all those methods abstract.

What you mean is what Java does with the default-implementations of some interfaces like TableModel - there is a DefaultTableModel which implements all methods from the interface and provides some basic functionality.

baka0815 Germany |

2/4/2012 10:23:57 AM #

David Heffernan

I'm struggling to work out what problem this is attempting to solve. It makes it easier to implement interfaces? Well, I never knew it was hard to do so. The abstract base class could be removed and the code would be just as intelligible.

David Heffernan United Kingdom |

2/4/2012 11:16:34 AM #

Brian Frost

Sometimes creating a separate class like this improves visibility but you can easily end up with lots of links in your code simply 'wiring things up'. My method for implementing interfaces is to copy and past the interface declaration into the implementor class and then use code completion to create the routines. It's much clearer then what is going on. An even slimmer solution is to declare the interface in a text file and then include {$Include MyInterfaceDef.txt} everywhere. I dont do this because the discipline of have a copy of the interface declaration in two (or more) places gives you time to think about whether you are architecting it correctly!


I prefer to include my interface declarations in a single class and then use

Brian Frost United Kingdom |

2/5/2012 2:06:53 AM #

Colin Johnsun

No worries! I'm just standing on the shoulders of others.

Colin Johnsun Australia |

2/6/2012 3:13:29 AM #

Rubén Valls

Hi, I think this pattern goes against your last posts about code decoupling. You are just know coupling your code to this abstract class.
Furthermore, if you separate this class in a "core" package (i.e. to implement pluggins), all the plugins will be dependent of this package, so any change to the package will requiere the entire rebuild of all the pluggins, while in the other hand, if you only depend on the interface, this is no longer the case (you should recompile everything only if you change the interface definition).
If you don't want to rewrite all the code for all the pluggins (like using inheritance), just use the "delegate pattern" (I don't know if it actually exists):
Just add events to the interface definition, create your base class which implements this interface and calls the event handlers, and use it in the actual pluggin class with a property with the "implements" keyword. You can use the event handlers you need, without rewriting the entire code. Or even you can have two interfaces, one for the plugin, and one for the delegate, and don't use event handlers, but querying the interface of the delegate!
But now, are you coupling again to a base class? No, you can use DI to get the base class, because you don't need to know which class it is in design time, because your plugin class inherits from TInterfacedObject, not from TBaseClass.

Best regards,
Ruben

Rubén Valls Spain |

2/13/2012 3:56:28 AM #

David S

An Interface in Delphi is analogous to a Pure Virtual Base Class in C++.  It's a class composed completely of abstract virtual methods that have no implementation, and you're required to override them in any derived class.

The difference in Delphi is that abstract virtual methods contained in classes are not forced by the compiler to be defined; you can leave them undefined if you don't mind compiler warnings.  But I believe an Interface MUST have all of its methods defined in a derived class.  

So the value of this is that you define the PVBC (as the Interface) and then immediately derive a concrete sub-class that implements all of the required methods.  If you then use this concrete class as your "base class", then you've got some useful (hopefully) default implementations that you aren't required to override.

Either way, it's a template that all derived classes must follow.  (Agreed, it's closest to the Template pattern.)

I also think the example is too simplistic to communicate clearly what benefits might accrue from the use of this pattern.  I like the example Colin gave.  But I'd like to see one that demonstrates how this is useful for alternative implementations.

I have to admit, I don't use Interfaces (or PVBCs) very much, because it seems that every class that I'd consider them for ends up having structural variations between the implementations, most of which I seem to always want to migrate into the base class.  Of course, that suggests that I'm not working on a sufficiently abstract level of the problem.  But you can't alway identify every possible variation in implementations prior to codifying the Interface specification, and before long, you run into things you "missed" that really belong in the Interface.  Unfortunately, at that point, it can be too late.

The flip side of that is to create Interfaces that contain some generalized methods that render data as serialized streams (eg, name/value pairs passed in a stringlist), thus bypassing the need to define specific accessors in the Interface for all possible options.  So instead of tightly coupling the code to the class, you tightly couple the code to some implementation-level data values.  (I personally don't like this approach, but I've seen it used more than I like.)

-David

David S United States |

2/15/2012 2:22:31 PM #

David Robb

There are actually two patterns here:

1. Static public methods in a base class, with each public method calling a virtual, abstract strict protected method to be implemented by descendants.  Perhaps a non-abstract "default" implementation is provided for some methods.  This is the template method pattern mentioned in an earlier post by Colin.


2. A "base" class that implements an interface where the base class perhaps provides a default implementation in some non-abstract methods.


I use variants of pattern (1) constantly, to the extent that I would like better language support for the pattern (this is another topic!).  Pattern (2) isn't as useful, and doesn't take advantage of some capabilities of interfaces, such as not being tied to a class heirarchy.  I can see it being useful from time-to-time, however, especially when combined with the template method pattern.


There are advantages to the template method pattern:

1. It makes it possible to inject code that impacts all descendants without verifying that each descendant calls the inherited method, and without consideration as to <i>when</i> the descendant calls inherited.  Consider, for example, the public, static methods Start and Stop.  In the original implementation I might write:

procedure TMyClass.Start;
begin
  DoStart;
end;

procedure TMyClass.Stop;
begin
  DoStop;
end;

Because I have made my public methods static, I am free to insert additional behaviors into these methods without fear of breaking the original contract exposed by the methods in their original incarnation.  In other words, as long as Start continues to call DoStart, I can feel free to add new code to the method before or after the call to DoStart.

For example, later, after I have written twenty descendants of this class, I might determine that we want to record in the log file whenever these methods are called (or maybe we want to update status or perform some other activity):

procedure TMyClass.Start;
begin
  Log(Format('Starting %s', [Name]));
  DoStart;
end;

procedure TMyClass.Stop;
begin
  Log(Format('Stopping %s', [Name]));
  DoStop;
end;

I can modify the base class with absolutely no fear of breaking any descendants of this class, and can simultaneously be certain that the logging will always occur whenever Start is called regardless of any code that a descendant may contain.

Or perhaps I want to guarantee that Start calls Stop if DoStart raises an exception (a variation of the constructor/destructor pattern that Delphi uses):

procedure TMyClass.Start;
begin
  try
    Log(Format('Starting %s', [Name]));
    DoStart;
  except
    Stop;
    raise;
  end;
end;

Later, I might decide to add a Started property and only call DoStart if a user of the class hasn't already called Start:

procedure TMyClass.Start;
begin
  if not Started then begin
    Log(Format('Starting %s', [Name]));
    DoStart;
    Started := True;
  end;
end;

procedure TMyClass.Stop;
begin
  if Started then begin
    Log(Format('Stopping %s', [Name]));
    DoStop;
    Started := False;
  end;
end;

Again I can make these changes without fear that they will fail to function as written.  This behavior is part of the <i>contract of the class</i>, and following patterns like the template method pattern help you to honor the contracts exposed by your classes consistently.

An important paragraph from the Wiki article on the Template method pattern:

The Template method pattern is strongly related to the Non-Virtual Interface (NVI) pattern. The NVI pattern recognizes the benefits of a non-abstract method invoking the subordinate abstract methods. This level of indirection allows for pre and post operations relative to the abstract operations both immediately and with future unforeseen changes. The NVI pattern can be deployed with very little software production and runtime cost. Many commercial software frameworks employ the NVI pattern.

David Robb United States |

2/16/2012 1:17:45 PM #

Nick Hodges

Great post -- thanks, Dave.

Nick Hodges United States |

2/20/2012 9:55:17 AM #

David Robb

Wanted to point out a confusing error in my previous post.

Pattern 1 is the NVI pattern.  Pattern 2 is the template method pattern.

Sorry about that!

Dave

David Robb United States |

Comments are closed

A Little About Me

Hey, I'm Nick.  I'm interested in Software Development, Leadership, and Basketball.  I'm a big fan of Delphi, but love all cool programming languages.

A Pithy Quote for You

"It is difficult to get a man to understand something, when his salary depends upon his not understanding it."    –  Upton Sinclair

Little Buttons and Stuff

Nick Hodges

Create Your Badge
View Nick Hodges's profile on LinkedIn
profile for Nick Hodges on Stack Exchange, a network of free, community-driven Q&A sites
Powered by DiscountASP.net
Join Dropbox

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.

Book Stuff

Earn Free Stuff

Search & Win