Sunday, August 15, 2010

Version-ed interfaces to refine a product specification?

Warning! This is just an idea. You will have to prove its value yourself!

Interfaces as product specifications
Nothing new here.
An interface defines some behavior that can be implemented by one or more classes.

Interface methods and properties
  • define inputs and outputs (interfaces as arguments and return types),
  • may have annotations (attributes that means something), and
  • have documentation (e.g. with references to specifications and/or examples).
Version-ed interfaces
Here comes the first idea.
Lets say that a product release of some features are to be version 1.
Here is what a (wacky) coder could have produced to materialize one of those features:

The 1st idea is to name the interface with a version number.

"Thats just insane! Why would you do that! ....."

Usually we don't change the name of the interfaces and it works fine, but lets see the next Foo specification:

This certainly is a bit strange. Apparently, now a Foo does not drink stuff from the bar, but only buys it. Definitely, strange.

This version 2 interface is renamed, specializes the previous interface by inheriting it and redefines the Bar method by using the new keyword.

Thats 3 things that you normally do not see:
  • The rename: It will have no effect on existing version 1 implementation, but require your implementation to be changed when it is to support version 2.
  • The specification inheritance: This is a very explicit way of tracking the specification history that might suite coders just fine.
  • The redefine with new: The Bar signature did not change, but the textual specification did. If the interface was named IFoo and the text just changed between version 1 and 2, then the compiler would eat everything just fine, but the version 1 implementation would still make Foo drunk whenever he went to the bar.
Implementation changes
Here is how a version 1 implementation could look:

The version 2 could be:

A tiny difference, but a fatal one when on a date!


2 comments:

  1. Interesting idea! With the help from modern IDEs, the task of switching (search/replace) from V1 to V2 is not as tedious as it used to be. Also, with the inheritence between V1 and V2 it is not necessary to upgrade legacy code to use V2 (unless V2 introduces new methods that the legacy code must use).

    But how would you handle changes in method signature? Create a new method with the same method name, or make sure to change the name also?

    ReplyDelete
  2. Hi Pelle,
    Sorry for being slow, but for some reason I got no notification mail from blogspot when you added your comment.
    > But how would you handle changes in method signature?
    If you are thinking about how to invalidate a version 1 method when releasing a version 2 method, it would be nice if we could choose between doing it softly (non-breaking) or in a harsh manner (breaking).
    A soft way could be to new the method in version 2 and annotate it with the Obsolete attribute (mark it as deprecated). It will then generate a compile warning when used.
    A harsh way doesn't really exist as far as I know e.g. to force a deprecated method - specified by an interface - to throw a runtime exception if used.

    ReplyDelete