Well, if you do eventually find yourself in need of exposing a public interface from your application, what’s the right way to do it?
First, a definition, though.
By public interface, I’m talking about some manner of exposing functionality within your application to the outside world. What you do with your BAS files, and private CLS files, not to mention FRM’s, or the all-encompassing VB.NET *.VB file is your own business. But what the world sees, or, more appropriately, has to deal with, is another matter altogether.
There’s a pile o’ ways to expose functionality from an app, especially a VB app.
First, a few old school methods….
- DDE – Yeah, it’s still alive. Want proof? Just boot up a copy of Vista, load REGEDIT and search for DDEEXEC in the HKCR hive. But seriously, you don’t want to go there.
- Windows Messages – SendMessage/PostMessage. They’re not just for subclassing and peeping toms. DDE and even COM relies on the Window Messaging subsystem to work. Your apps can leverage it too. But really, that’s a whole lot of pain for not a lot of gain, so why bother?
- DLL Entry Points – There are several tools out there that make exposing DLL entry points from a VB application relatively easy to do. In some cases, this is how you have to expose functionality (as in when some other app only makes calls to DLL entry points, and you want that app to talk to yours). But using this technique to expose your own functionality to the world just seems so, well, reagan-omic.
And the more common techniques….
- COM – The classic VB PUBLIC class. All you gotta do is change your class’s interface type to PUBLICNOTCREATABLE, MULTIUSE, or GLOBALMULTIUSE and biff boom pow! Anyone can use your class, right?
- .NET Assemblies – Same as COM, but shinier
OK, COM (or .NET assemblies) it is (I’m going to consider the two the same for now, what sacrilege!)
So how do you do it?
There’s piles of books on the mechanics of the task, so I’m not going there. Just look at Kurata’s Doing Objects in Visual Basic 2005 or Dan Appleman’s various books on ActiveX techniques for those kinds of details.
What I’m talking about is which interface design is most appropriate.
Kinds of Interfaces
Generally, I’ve seen these designs gather into 3 camps:
- The massive wad of hierarchically related objects. This is the Outlook, Word or Excel object models.
- The single public class containing all the functions you could ever want. Not terribly common; I see it most is 3′rd party utility libraries.
- And finally, the single class with a single (or at most very limited set of) functions that serve as a “command line” of sorts where you might pass in a parameter that is the “operation” and that additional parameters that are the “arguments for the operation”. The GroupWise API is a great example of this.
The Massive Hierarchical Wad
- Easiest to program against. Intellisense, separate objects, etc speed working with your model.
- Hardest to keep compatible. Even minor changes from one version to the next of your application can render it incompatible with previous versions of your application, causing loads of headaches for your users.
The Single Class
- Relatively easy to program against. Intellisense will help. So does consistent naming of all those methods and properties.
- Works well for relatively minor amounts of exposed functionality.
- Generally considered bad practice.
- Suffers from compatibility headaches much like the Massive Wad.
The Command Line Class
- Essentially immune from direct interface compatibility issues, since the lone interface is flexible enough initially to never have to be changed.
- More difficult to code against. Intellisense only helps with the command line function itself, not with each of the commands that can be sent.
- Moves compatibility issues to the user. If new functions are introduced, it’s the users responsibility to test for the version of the application and react appropriately.
So, what’s the final word?
As usual, there’s really no right answer.
Personally, I tend to stay away from the “Single Class”, simply because it has all the difficulties associated with the Massive Wad, and none of the immunity of the Command Line Class; the worst of both worlds.
The Command Line Class is most useful when your exposed function points number in the 10-100′s. Any more than that, and it starts to become unwieldy, though it’s still perfectly workable.
The Massive Wad is the most traditional, most familiar style of public interface to those who’ve likely used public interfaces of other systems. That’s not to say it’s the best option, just that’s it’s the most typical.
How about it? What kinds of public interfaces have you built and put out there? Is there a style I’ve missed. Maybe something better than any of these?