Amazon.com Widgets February 2012

I don’t want to hear another frackin' negative word about Embarcadero Marketing.

By Nick at February 26, 2012 18:19
Filed Under: Delphi, TechBiz

Not one more word.

For many years, it has been very fashionable to say how “[Borland|CodeGear|Embarcadero] sucks at marketing”.  You could very easily establish your bona fides by bashing Delphi marketing.  Everyone knows that Borland always sucked at it, and all the cool kids say so, right?

Well, I think those days are over.

What is Marketing, Anyway?

First of all, I’m guessing that about 99% of the people saying this didn’t understand the difference between “marketing” and “advertising”.  They aren’t the same, just so you know.  They overlap, but they aren’t synonymous.  The Wikipedia page for marketing starts out with "Marketing is defined by the AMA as ‘the activity, set of institutions, and processes for creating, communicating, delivering, and exchanging offerings that have value for customers, clients, partners, and society at large.’"  My personal definition is “whatever you do to make people aware that your product is for sale and what the reasons are that they should buy it”. 

Sales and marketing are related, but very different.  In general, marketing’s job is to create leads for sales to act upon. 

I think that the root of much of the complaining over the years has been the result of a lack of advertising.  People who don’t see advertising think that there’s no marketing going on.  Marketing is much more than just running ads.  Marketing activities include, but are very much not limited to, advertising. In fact, some of the most effective marketing is that which requires zero advertising.

For instance, Dropbox has a brilliant marketing strategy that has been amazingly successful and requires exactly zero budget for marketing or advertising. What do they do? They get people like me to try to get people like you to sign up. The more people sign up, the more potential paying customers they have. They give away 2GB of space (which probably costs them something like $0.000001….) and then induce those folks to do their marketing for them. They have been enormously successful doing this. They spend zero money on advertising, but they have a fantastic marketing plan that makes millions of people aware of what they have to sell. Awesome.

Delphi Marketing in the Past

I’ll concede that the marketing of Delphi has been historically “limited” or “hard to find” . I’ll not concede that it has been “bad” or “terrible”. The marketing itself has been good – there just hasn’t been enough of it.  Marketing success is largely a function of budget, and over the years, and the budget for marketing Delphi has not always been huge. As noted above, there isn’t a direct relationship between marketing and money, but certainly money is a big boost.  Limited budgets have made it harder to market Delphi, but that doesn’t mean that the marketing that was done was done poorly.

Despite limited budgets, here has always been marketing going on around Delphi.  Every new release resulted in many activities, a “world tour”, webinars, etc.  And here’s a key point to remember:  if you are an existing customer, then marketing to you is fairly easy. You already know the products and benefits.   To a large degree, efforts spent on marketing that you see is wasted effort.  The perfect marketing plan would be visible only to non-customers and invisible to existing customers.  And here’s the second thing to remember -- if you know that Delphi is on version XE2, and even the basics of the current feature set, then you have been successfully marketed to, whether you want to admit it or not! That’s always been the case – if you knew about the latest release and it’s features, you were successfully marketed to. 

Delphi Marketing Today

However, over the last few years, things have been getting better.  And over the last year or so, things have gotten, well, really good.  In that time, I’ve seen a marked and obvious increase in marketing activity and an rise in the quality of things done for Delphi and Embarcadero products in general.  Clearly someone has decided to spend some money and make it a point of emphasis. 

I now see the following on a regular basis:

  • First, the overall outbound communication in general has steadily picked up.  I now see people who for years didn’t hear a peep from the Delphi marketing team now complaining that they are getting too many emails.  Some are even upset that their sales representative has called them.  Yeah, that’s terrible!  I myself had a very nice chat with our sales person last week --  they were pleasant, knowledgeable, and helpful.  We probably won’t be upgrading our licenses until next year, but they were happy to know that, and interested in hearing my feedback on a wide variety of things, including the product, the marketing efforts, and other things of concern.  I appreciate a vendor that takes the time to hear me out.
  • A steady stream of webinars on a wide range  of topics.  It seems that at least once a month, they are conducting a webinar of some sort, on topics ranging from Delphi to database design and enterprise architectures.  I get very professionally done emails, I sign up, they remind me about the event, and they follow up with emails after.  If I miss it, they send an email saying “Sorry we missed you, here’s the replay”.  As a result, you see their products in action, you learn the new features, and you are steadily reminded that the product is there.  Excellent work.
  • When they aren’t doing webinars, they are letting me know about White Papers that well known Delphi community members have written.  There a lot of them available, and a steady stream of new ones coming online.  Nice.
  • I haven’t seen them recently, but for the last few years, Embarcadero has had a full page advertisement in every issue of SDTimes.  I’ve also seen banner ads on the SDTimes website. 
  • And while on the subject of ads, I see Delphi banner ads all over the place.  They clearly have paid Google for the adwords, and since Google knows I’m a Delphi user, I see ads for Delphi and RAD Studio all over the web.  Nice.
  • They also appear to have bought keywords on StackOverflow.  Try this – log out of StackOverflow and go the Delphi tag page and see what you get on the right side.  (If you don’t any reputation at StackOverflow, you don’t have to log out – they stop showing ads after a certain reputation score).
  • For a long time, the Borland/CodeGear/Embarcadero website was….less than helpful.  However, now, it is really well done.  Checkout the Delphi page.  It’s visually appealing with a  good highlight of the product. Easy to find links take you to the Product Edition page, a page showing cool third-party stuff, and free resources out on the web, among other information  And of course the page has a clear “call to action”, either buy or download a trial.  This is a very nicely done web page.
  • And if the webinars were not enough, the Developer Relations team did an excellent (and well attended, I might add…) series of live seminars all over the world.  These were well advertised and well run.  They included user group events during week nights, and for the first time. some day long events on Saturday.  In talking with the DevRel folks, I know that these were particularly successful.  I had the honor of being the guest speaker at two of them, in Washington, DC and in Newark, NJ.  Over the last year, the team has also put on a CodeRage event, the 24 Hours of Delphi, and a Delphi Birthday Party.  The hits just keep on rolling.
  • The marketing department even has a blog – The Delphi Insider – run my by friend Tim Del Chiaro.  If you want to  know everything that is going on, that is a good place to start. And of course, there are a number of active (an inactive, sadly) blogs on the Embarcadero servers.

The folks marketing Delphi are doing some really good work, and we should appreciate and recognize it.  Embarcadero has clearly stepped up its game, and we should all give credit where credit is due.

Flotsam and Jetsam #56

By Nick at February 25, 2012 02:24
Filed Under: Delphi, Flotsam and Jetsam, Personal

On the Proper Design of Exception Hierarchies

By Nick at February 19, 2012 22:13
Filed Under: Delphi

Introduction

Exceptions are all over the place in Delphi.  Introduced way back in Delphi 1.0, they totally changed the way that folks looked at error handling.  Previously, we’d do things like:

ErrorCode := DoSomething;
if ErrorCode > 0 then 
begin
  DoNormalStuff;
end else
begin
  UhOh;
end;

We had to constantly interrupt the flow of our code in order to make sure that all is well.  Exceptions changed all that by letting you put all the error handling at the end, in a try…except block – out of the way of the flow of your code -- where you could handle things separately, leaving you to worry about how things should go, and not how they might go wrong.

Way back for Borcon 2004, I wrote a paper on exception handling called “Exception Handling for Fun and Profit”.  You can read that and get a good idea on the proper way to handle exceptions.  It is eight years old, but it’s still all good advice.

What I want to talk about here, though, is the best way to write your own exception classes and exception class hierarchies.  The Runtime Library gives you a number of Exception types, and it uses most of them.    You are, of course, free to use any of those exceptions declared in SysUtils.pas and elsewhere, and of course you can simply create an exception from the base class Exception. But most often when writing your own library code, the standard exception classes are not enough.  So I’m going to try to give you some ideas on how you can and why you might create your own exception classes.

A note before I start: Exception hierarchies should be part of library code; that is, code you write for use by other applications. As noted in my aforementioned article on exceptions, application developers should trap exceptions, and library code writers should raise exceptions. Exception hierarchies are part of developing library code, so this article really only pertains to that side of the fence.

The Basics

The first thing I’ll tell you is that you should never raise a plain exception:

raise Exception.Create(‘An error occurred’);

I can’t think of any reason for ever doing that.  It provides no useful information about the type of exception and why the exception being raised, leaving consumers of your code with little helpful information.

So, as you’ve probably noticed,  I like to say “You should never do <this>”.  And of course, when I do that, it’s incumbent on me to say what you should do instead.  So here goes.

First, you should always raise a specific exception for a specific exceptional situation.  If it’s a “normal” exception, use on of the standard Exception classes that are part of the RTL.  For instance, if you are dealing with streams, and you have an error, you might raise an EStreamError

Most often, though, you want your exception to be as precise and exact as possible.  This way, it will be easier to pinpoint exactly what went wrong when the exception is captured and displayed.  And in order to do that, you should create your own exception hierarchy.  If an existing exception type isn’t perfect for the situation, then don’t be afraid to define one that is.

And when you do that, the hierarchy you create should be flat and wide.  Flat and wide exception hierarchies allow for the simple organization of similarly purposed exceptions.   Here’s what I mean by that.

Flat and Wide

I’ll use my class library THTMLWriter as an example.  It it, there is a unit called HTMLWriterUtils.pas that contains the following code:

type
  EHTMLWriterException = class(Exception);
    EEmptyTagHTMLWriterException = class(EHTMLWriterException); // Tested
    EOpenTagRequiredHTMLWriterException = class(EHTMLWriterException); //Tested
    EHeadTagRequiredHTMLException = class(EHTMLWriterException); // Tested
    ETryingToCloseClosedTag = class(EHTMLWriterException); // Tested
    ENotInListTagException = class(EHTMLWriterException); // Tested
    ENotInTableTagException = class(EHTMLWriterException); // Tested
    ENotInCommentTagException = class(EHTMLWriterException); // Tested
    ENotInFieldsetTagException = class(EHTMLWriterException); // Tested
    ENoClosingTagHTMLWriterException = class(EHTMLWriterException);
    ENotInFrameSetHTMLException = class(EHTMLWriterException); // Tested
    ENotInMapTagHTMLException = class(EHTMLWriterException); // Tested
    ENotInFormTagHTMLException = class(EHTMLWriterException); // Tested
    ENotInObjectTagException = class(EHTMLWriterException); // Tested
    EClosingDocumentWithOpenTagsHTMLException = class(EHTMLWriterException); // Tested.
    ETableTagNotOpenHTMLWriterException = class(EHTMLWriterException); // Tested
    EParamNameRequiredHTMLWriterException = class(EHTMLWriterException); // Tested
    ETagIsDeprecatedHTMLWriterException = class(EHTMLWriterException); // Tested
    ENotInSelectTextHTMLWriterException = class(EHTMLWriterException); // Tested
    ECaptionMustBeFirstHTMLWriterException = class(EHTMLWriterException); // Tested
    EBadTagAfterTableContentHTMLWriter = class(EHTMLWriterException); // Tested
    ENotInDefinitionListHTMLError = class(EHTMLWriterException); // Tested
    ECannotNestDefinitionListsHTMLWriterException = class(EHTMLWriterException); // Tested
    ECannotAddDefItemWithoutDefTermHTMLWriterException = class(EHTMLWriterException); //Tested

This is an example of a “flat and wide” exception hierarchy.  The hierarchy is “flat” because there are only two levels of inheritance – the base class and a large number of descendants.  A class diagram of these classes would be “flat” because there isn’t much distance from the top to the bottom of the inheritance.  It’s “wide” because there are a lot of sibling classes on the second level of inheritance.  The class diagram would take a lot of horizontal space if it were laid out on paper.

How does this all work?  First, I declared a base type, EHTMLWriterException.  All the exceptions raised in the THTMLWriter library will be a descendant of this type.  As a result, you can easily check the type of an exception, and if the type is EHTMLWriterException, then you know what library raised the exception.  When you are using the THTMLWriter library, you can easily trap all the exceptions raised by the library within your exception handling code by simply calling:

try
  //code that raises an exception in THTMLWriter....
except
  on E: EHTMLWriterException do
    //you know that the exception came from THTMLWriter
end;

Second, I declare a large number of very specific descendants that are raised in very specific situations.  Their names are very descriptive, and they are usually raised only in one place – the exact place that the error occurred.  This makes locating the cause of the exception much easier.   Precisely named exceptions can be easily searched for in code.

An Example

For instance, here’s an example of some code calling a very specific exception:

function THTMLWriter.OpenParam(aName: string; aValue: string = cEmptyString): IHTMLWriter;
begin
  CheckInObjectTag;
  if TStringDecorator.StringIsEmpty(aName) then
  begin
    raise EParamNameRequiredHTMLWriterException.Create(strParamNameRequired);
  end;
  Result := AddTag(cParam)[cName, aName];
  if TStringDecorator.StringIsNotEmpty(aValue) then
  begin
    Result := Result[cValue, aValue];
  end;
end;

Here you can see that the code raises an exception named EParamNameRequiredHTMLWriterException.  The class name alone tells you that it is an error from the THTMLWriter library, and that it was raised because a parameter name was required but not found when the call was made.  Just the exception’s class name has a lot of information.  In addition, you’ll note that when I raise these specific exceptions, I include a very specific, detailed error string explaining what happened.  In my view, you can’t have enough information in an error message. 

Thus, if you end up raising this exception, you’ll get this:

image

Given all that, if you can’t figure out exactly what the problem is and exactly where it occurred, well, then I’m not sure you are in the right business.  Winking smile

Lots and Lots of Exception Types

Since it is fine – and even desirable – for exception hierarchies to be wide, you shouldn’t be shy about declaring many exception classes as direct descendants of your one main exception class.  You’ll note above that even in a small library of code like THTMLWriter, I’ve declared 23 exception types.  I see nothing wrong with having a large, very specific set of exceptions that you can raise throughout your code library.  As I said before, if your exception type is only raised once, that’s fine – it’s very easy to find the location of an exception that is only raised in one place. 

Conclusion

So there it is – make your exception class hierarchies flat and wide, use good exception messages when raising them, and you’ll enable the consumers of your code to easily see where problems are arising and to quickly deal with them when they do.

My Amazon Kindle So Far

By Nick at February 12, 2012 06:59
Filed Under: General, Tech Stuff, TechBiz

A while back I wrote about why I got my Amazon Kindle Fire, and in that post I promised you that I’d write about my thoughts about owning the Kindle.  And since I’d rather rub shredded fiberglass in my eyes than break a promise to you fine people, here are my thoughts on owning an Amazon Kindle

  • First, I want to say that I also am an Amazon Prime customer, so what I talk about below may include benefits of being in Amazon Prime.  Those benefits are actually quite numerous considering the $79 annual price tag.  If you are at all involved with Amazon, I’d give the Prime membership a good look.   You can save a lot of postage – and a lot of time and gas – with Amazon Prime.  “Gas, you say? How?”  Well, I’m glad you asked.  Here’s an example:  I don’t drive to the Pet Store anymore, because I just have Amazon ship me – at no charge and with no sales tax – my dog food.  And cat food .  And that is just the beginning of what Prime offers.  I’ll leave it now to say that it’s a pathetically good deal if you have even the remotest notion of buying things from Amazon, and point out some more specific things as I go along.
  • The second point to make is that at $200, the Kindle Fire is pretty much a loss leader for Amazon.  I don’t know for sure what it costs to make the Kindle Fire, but I’m guessing that Amazon is selling them at a loss or very close to it.  And the reason is that the Fire is, in Amazon’s eyes, merely an Amazon content delivery device.  They want to get this device – a Kindle – into your hands. At $200, it’s an attractive tablet that runs Android apps, had a dual core processor, a color screen and has all the advantages of a Kindle.  Sure, any tablet can run Kindle software, but as a Kindle, I  can do things like borrow a free book a month from the Kindle Owners' Lending Library (another Prime perk….) as well as watch Amazon Video (another Prime benefit…) on the device.  I can store all my Kindle content (another Prime benefit….) with unlimited space on the cloud, including magazines, books, and music. 
  • The Kindle Fire is pretty impressive hardware. It is a dual core processor, and a very nice seven inch IPS screen. I haven’t really ever thought that it was slow because of processor power. It seems plenty powerful to me.
  • Things I like to do with a tablet (and that don’t really matter that it’s a Kindle Fire….)
    • Read Twitter.  I’ve taken twitter off my phone because now I can….
    • …actually read the web article on a link from Twitter instead of putting it in Instapaper because my phone makes it too hard to read the link. 
    • Watch movies and TV in bed with a nice, crisp seven inch screen. The Fire is really easy to hold however I like.
    • Play games. The screen is big enough to actually see the cool graphics on some cool games. I’ve taken all games off my phone, and the Fire has become a nice little tool for wasting some time.
  • Things I like to do with my Kindle fire (because it is a Kindle…)

Miscellanea:

  • Nice: One thing I like is the “Lock screen” feature which locks in screen orientation.  Sometimes you want to lie on your side and still read in portrait mode even though you are holding the device in landscape mode.  I like that. I suppose that  other tablets have that – I don’t know – but I do like it’s easy access.
  • Nice: Amazon's Android AppStore gives away a paid app every day.  Mostly it is cheesy games, but every once and a while you can get a nice paid app.  While not the Android Market, you can get many of the apps you want from the Amazon AppStore, including things like NetFlix, Pandora, Evernote, etc. 
  • No Google apps, though.  I guess I’m not 100% clear while Amazon blocks Google apps. I guess they view them as a competitor. I sure would like to be able to run Google Mail and Google Calendar on it. I also prefer Google Music, but Amazon’s music is workable. It is a bummer not to have the Google/Tablet connection.
  • To add insult to injury regarding the above note, there really isn’t even a decent third-party calendar app in Amazon’s store. Alas.
  • Bummer: The device has no camera, no microphone,  and no GPS.  This is okay, because the GPS on my phone works much better when I’m driving.  The camera on my phone is as good as any they’d put on the tablet.  I pretty much have my phone with me all the time, so those missing features in the Fire aren’t a problem. 
  • Bummer:  The Kindle Fire runs Android, but it is a very customized and restricted version of Android.  As a result, the device has no Google apps, including no access to the Google Market.    However, if you want, you can root it (though if you do, you lose the ability to watch free Amazon Prime videos).  You can then sideload the Google apps.   You can sideload apps without root access, but it is a bit of a crap shoot whether any given app will work.  (Here’s a good open letter to Jeff Bezos on this topic, the general sentiment of which I support.  I don’t’ regret my Kindle purchase, but it would be a really, really awesome tool if I had the Google stuff on it.)
  • A Bit Strange: There is only one physical button on the whole device:  the power switch on the bottom.  This means no volume rockers, which Android users are kind of used to, I guess.  It hasn’t bothered me too much, but I know that it is something that bothers other users.
  • Bummer:  Amazon advertises their custom Android Silk browser as “lightening fast”, but my experience has been, uhm, different.
  • Nice to Know: I have kept my device “Kindle-ized”, but if I wanted to, there are Android ROM’s available for the Kindle Fire if I wanted to move the device to be a “pure” tablet.  But again, I’d lose the advantages in Amazon Prime of the device being a Kindle.

Final verdict:  I’m happy with my Kindle Fire – I like using and having a tablet – but I’m going to save up an buy a “real” tablet in the fall.  I’m interested in the Google Nexus Tablet – or at least in concept.  I like having a Nexus phone, and I’d like to have the same thing in a tablet.

Flotsam and Jetsam #55

By Nick at February 08, 2012 18:02
Filed Under: Flotsam and Jetsam, Delphi
  • Marco notes that Embarcadero has put out a press release announcing a 54% increase in revenue in 2011 over 2010.  This is unequivocal, clear, unassailable good news.  No amount of Chicken Little whining will take away from the fact that this is very, very good news.  (It didn’t take long for Marco’s commenters and the Nattering Nabobs of Negativity in the non-tech newsgroups to try to find a way to make this something other than great news.)  The most important thing that the EMBT Executives care about is the bottom line – and that is how it should be.  And the bottom line for Delphi apparently looks pretty darn good – good enough for them to brag about it.  When the bottom line of Delphi looks good, that is good for Delphi developers. 
  • Hey, I noticed that I’ve gone over 1000 comments here on my blog (actually it’s more like 3000  if you count spam that I’ve deleted.….).  Thanks to everyone who posts comments.  I appreciate you reading this stuff I write, especially when you go to the trouble of writing something up and adding to the conversation.  Lately some of the discussions on my technical posts have been really good – I’m grateful.
  • I am not myself able to go this year, but I’m quite happy that three of my team here at Gateway Ticketing will be attending Delphi Developer Days this April in Baltimore/Washington, DC.  I was there last year, and I can tell you that it was a really valuable experience, and I recommend that you attend this year if you can.
  • Jason Southwell’s ApeSuite for FireMonkey has a new beta out with a bunch of new features.
  • More FireMonkey components are now coming from TMS Software as well – they have a cool set of instrumentation components as well as a TableView control that will be popular for folks writing mobile apps in particular.
  • And Even More FireMonkey: As previously noted, I haven’t played with FireMonkey  much, but I have to confess, it is cool to think that this demo app – as described by Anders Ohlsson in his EDN article – is written in Delphi and will run on the Mac (and even iOS I guess…?) as well as on Windows.  Pretty slick.  And while you are at it, check this one out as well.

…Wherein I Rant Vigorously About Mobile Twitter Clients

By Nick at February 05, 2012 00:23
Filed Under: TechBiz, Tech Stuff, General, Delphi

I am now going to go on a rant about Twitter clients – mobile Twitter clients in particular (though some desktop clients are rant-worthy as well).  I am going to do this because I can’t understand why they are such a pain in the ass and work so badly, when they could so easily work so well.

Okay, first, don’t get me wrong.  I really like Twitter.  (If you want, you can follow me, I’m @nickhodges --  no surprise in that handle, eh?)  I like it because it’s a great place to keep up on news, find interesting articles, read funny stuff, and to post your thoughts in short, pithy statements of 140 characters or less.  It’s also a great time killer.  If you are waiting at the doctors office, it’s a much better way to pass the wait than looking at a two and a half year old copy of People Magazine.  It’s interesting, fun, never the same thing twice, and frankly, I’m a little addicted.  I do almost all of my twitter reading on my phone or on my wonderful Amazon Kindle

But yet reading Twitter on my mobile devices drives. me. crazy.  When it comes to mobile Twitter clients, I’m not addicted -- I’m inflamed with a rage that burns like the heat of a thousand suns.

I’ve tried just about every one out there. They all drive me insane.  And so here is  my rant:

  • A twitter client should never, ever, ever, under any circumstances, for any reason, at any time, ever, ever, EVER move my “cursor”.  EVER. And by “cursor” I mean my location in my Twitter stream.  I determine where my cursor goes, not you, you blasted twitter client that thinks you can just show me whatever you want when you want to.  If I am reading Twitter on my phone, leave off on a funny Pauly Peligroso post, go away to another app, and then I come back, you darn well better have my twitter client looking right at that same stinking Pauly Peligroso post when I come back.  I don’t care if I’ve been gone for five minutes, five hours or five years, you flipping better have your cursor right there where I Ieft it. Not anywhere else.  Where. I. left. it.  Leave a gap if you have to. I don’t care, just leave it. Don’t try to do me a favor and “catch me up”.  If I need catching up, I’ll get myself caught up. Give me an option to get caught up, fine.  But for the love of Adam Sandler, DON’T MOVE MY POSITION IN MY TWITTER STREAM.   Ever,  ever, ever, never, ever, ever. 
  • Second, if you tell me that there are “143 new tweets”, and I say “Great, some new tweets”, put me at the freaking START of the 143 new tweets, not at the current time!!!!   Why in the name of sweet baby Dick Van Dyke would I ever, ever, ever what to start at the most recent tweet out of those 143 new tweets? Why would you tell me that there are 143 new tweets and then start me out at the point where there are zero new tweets? Why do I open up the fracking client and see some tweet from three seconds ago, when I want to read the 143 new tweets?  Why do I have to manually scroll down and try to figure out where the new tweets start?  What is that, some kind of sick, twisted joke?  Really?  I have to scroll?  Seriously?   I mean this is basically a variation of the “Never move my cursor spot”, but come on, this is ridiculous.
  • Third – stop trying to shorten my shortened URL’s.  I’m smart – I can shorten my URL’s myself.  It’s nice you want to do that for me, but at least let me opt out of it.  Nothing says “wasted time and resources” as a link that is a Twitter shortened version of a bit.ly link that started out as a tinyurl.com link.  I mean, come on, I can keep my twitter posts under 140 characters myself.  I don’t want your help.  I don’t need your help.  Stop it.

Bottom line: Mobile twitter clients stink and they make me want to bash public monuments with a sledgehammer. (I’d never do that, really, but I want to when I go back from checking my mail and the stupid TweetCaster moves me to  a tweet that was posted 23 seconds ago.)

Phew, okay, I feel better now.

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?

My Book

A Pithy Quote for You

"Good judgement is the result of experience ... Experience is the result of bad judgement."    –  Fred Brooks

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.

Month List