Programming to Interface – a real story
What constitutes a Public Interface, and where does it come from?
An object’s Public Interface is simply the set of Properties, Events and Methods (PEMs) that it exposes to its environment. Notice that the key word here is ‘exposes’. An object may (and usually does) have many more PEMs defined than actually appear in its public interface. This is because the purpose of the interface is not to define the full functionality of the object, but merely to define how other objects can interact with it. In other words, the interface defines the usage, not the implementation and, by that definition, only PEMs that are intended to be accessed, or manipulated, by other objects are exposed. Figure 1 shows the Interfaces for the Visual FoxPro Application object, and the methods (and some properties) exposed by the Public Interface ("Application").

Of course, the interface is defined by the class from which the object inherits directly, although that class need not, itself, define the entire interface. It may inherit either whole, or partial, interfaces from other classes. The actual mechanism and code by which interfaces are implemented is the responsibility of the developer and varies according to the programming language being used. However, the principles remain the same irrespective of implementation, which is what makes the concept of an interface so important when working with objects.
For example the whole basis of Microsoft’s Component Object Model (COM) rests upon the premise that:
A COM object is one in which access to an object’s data is achieved exclusively through one or more sets of related functions. These function sets are called interfaces, and the functions of an interface are called methods. Further, COM requires that the only way to gain access to the methods of an interface is through a pointer to that interface.
Thus all COM component interfaces (pre-defined or custom) ultimately inherit from a single ‘root’ interface called “IUnknown”. Components that support automation do so by implementing a specific interface, named “IDispatch”, which itself inherits from IUnknown. (Figure 1). This brings us to the real reason that interfaces are so important.
Objects that share a common interface are interchangeable
This is what gives OOP systems such enormous power and flexibility, In an application where functionality is delivered by objects, modifying functionality only requires changing the object, not changing the code. In other words, instead of having to modify existing code (adding the inevitable bugs as we do so) we need only create a new object that provides the required behavior and use it in place of the original. However, this is only achievable as long as both objects share the same public interface and is why rigid adherence to the concept of “programming to interface” is so important
Bridges rely on interfaces
The “Bridge” pattern is probably the most important, and certainly the most fundamental, of all object oriented design patterns. The classic definition of a Bridge is that it decouples an abstraction from its implementation so that the two can vary independently. The implication of this is that no object should ever rely on the internal workings (i.e. the implementation) of another object. As stated above, an interface merely defines how two objects should communicate without specifying how either implements any specific functionality. The only knowledge that one object should have of another is the set of exposed methods, their parameters (if any) and return values (if any).
To see how this works in practice consider that when writing code in forms and classes we naturally want to trap for things going wrong and usually (being considerate developers) we want to tell the user when that happens. The most obvious, and simplest, solution is to include a couple of lines of code in the appropriate method that pops up a window and displays some text. The result will look something like this:
IF NOT <A Function that returns True/False>
cErrorText = "Check failed to return the correct value" + CHR(13)
cErrorText = cErrorText + "Press any key to re-enter the value"
WAIT cErrorText WINDOW
RETURN False
ENDIF
In our application we may well have dozens of situations where we display a window like this to keep the user posted as to what is going on and this works perfectly well until one of two things happens. Either our users decide that they really hate these pesky little “pop-up windows” and would much prefer a more conventional windows-style message box, or, much worse, we need to deploy the code in an environment that simply doesn’t support “pop-up windows” (maybe as a COM component, or in a web form). We must now go and hunt through our application and find every occurrence of this code and change it to support the new requirement (whatever that may be!).
We don’t know about you, but in our experience the chances of getting such a task right first time (not missing any occurrences and re-coding every one perfectly) are so close to zero as to be indistinguishable from it. Even if we could be fairly confident of doing it, we still have the whole issue of testing it to deal with.
So what has this to do with the Bridge pattern? Well, the reason that we have this problem is because we failed to recognize that we were coupling an abstraction (displaying a message to the user) to its implementation (the “pop-up Window”). Had we done so we might have used a bridge instead and then we could have avoided the problem entirely. Here’s how the same code would look if we had used implemented it using a bridge pattern:
IF NOT <A Function that returns True/False>
cErrorText = "Check failed to return the correct value" + CHR(13)
oHandler = This.oMsgHandler
oHandler.ShowMessage( cErrorText )
RETURN False
ENDIF
See the difference? We no longer know, or care, how the message is going to be displayed (so we don’t even need the ‘Press any key’ line because we can assume that it will be added in the message handler if it is required). All that we need to know is where to get a reference to the object which is going to handle the display for us. It is that source of the reference that is the “bridge”. In this example the object’s “oMsgHandler” property provides the bridge between the code that requires a message and the mechanism for dealing with a message. Now, all that is needed to change the way in which our message is handled is to change the object reference stored in that property. That is something that could even be done at run time depending on the environment in which the parent object has been instantiated. This approach successfully de-couples the abstraction from its implementation and our code is much more re-usable as a result.
Now we can see how important the concept of an interface is to the bridge pattern. The implicit assumption behind the bridge is that all possible handlers will implement the appropriate interface. It is the interface that defines the method name (ShowMessage()) and parameters (a string to be dealt with) that all candidate implementations must follow.
Interfaces and Inheritance
Another example of the importance of interfaces is illustrated by the problem posed by the production of ‘output’ from an application. Such output can take many forms. It may be a printed report, a document sent via e-mail, an XML file sent to a different application, HTML sent to a browser, and so on. Clearly, the type of output required can vary widely between applications, between different parts of the same application and even at the same point in a given application depending upon user actions. This can result is some truly nightmarish code to handle the logic and deliver the correct form of output.
However, if all output is controlled by “output objects” that adhere to the same interface, it actually does not matter which one is used at any time. Each output object might have a single method called ReadData that accepts the required input and one called WriteData to produce the appropriate output. What each method does is irrelevant to the outside world. When a different form of output is required, a different object is selected, but the way in which you call that object does not change.
The flexibility that results from adopting this approach to design is independent of inheritance. Unfortunately, it seems that inheritance is the most over-used element of object-oriented technology even though it is actually the least flexible. This is because the inheritance hierarchy is defined at design time and there is no way to change an object’s pedigree at run time. Furthermore, subclasses inherit all of the characteristics of their parent class and, although it is possible to augment and specialize behavior in the sub-classes with well-planned hook methods, or by overriding inherited behavior, inheritance remains, essentially, a design-time tool.
The technique of selecting among several objects, all of which conform to the same interface, can be thought of as “run time inheritance”. By selecting a different object at runtime, you change the behavior of your application, but is possible only because you have programmed the application to a defined interface rather than a specific implementation. When you know what parameters the object’s exposed methods require, you can just package up whatever that object expects and, like a ball, throw it over the wall to that object. You do not need to know, and should not even care, what the object is going to do once it catches the ball. All you need to know is how to ask that object to throw the ball back when the object is finished with it.
The benefits of consciously programming to interface
So why are we bringing all of this up? Well, like most developers, we thought that we understood this concept. However, we were working on a project for a client that brought the importance of this technique home to us in a very practical sense. What we are going to show you is how you can reduce development time and, in general, keep your programming headaches to a minimum, if you adhere to the principle of programming to interface rather than implementation.
Let us start by telling you about the first meeting we had with the client to begin gathering requirements for their new Life Insurance Quote system. It went something like this:

From there, the transfer of ideas and communication went downhill!
Although our first thought was to create a table called “All-in-one” with one memo field called “everything”, it was clear that this approach would not work. We needed a model. But what information did we actually have? During that initial meeting, we had managed to agree that we had the following requirements:
-
Support multiple user interfaces including browsers
-
Support multiple databases including VFP
-
Interact with Microsoft Office applications; in other words, Automation
The logical design
Now we had to start making some design decisions. The main accounting system used by the client was written in Visual FoxPro and that system would be a major consumer of the output of the application. Since we needed to support multiple front ends as well as multiple back ends, we knew immediately that this was going to be designed as an n-tier application and with Visual FoxPro as one of the main client applications, it made sense to use VFP to build the middle tier components. We recognized that these classes might have to be instantiated directly by a VFP front end but still be capable of providing services for other front ends when compiled into a DLL. Since other applications do not understand VFP cursors, we would also need some sort of formatter object to convert cursors to XML that could be sent to a browser. This formatter object would also need to be able to package data in such a way as to provide data for Microsoft Office applications (we knew we would need to talk to both Excel and Word) in the form of ADO Recordsets.
The fact that we might have to support multiple back ends meant we would also need some sort of “converter” for non-VFP back ends. Furthermore, since the client was unable to give us the details we needed to build a complete data model, we were going to have to be prepared to modify our data structure early and often. In order to minimize the number of changes required as the data model changed, we decided to data-drive everything.
This meant that we were unable to use views because table and field details are hard-coded into the view definition. Instead, we decided to use a set of data classes that were, themselves, data-driven. (A discussion of data classes as an alternative to views is beyond the scope of this article. However, if you are interested in more details, see Chapter 13 in ‘1002 Things You Wanted to Know About Extending Visual FoxPro”, published by Hentzenwerke). It is sufficient for the purposes of this discussion to say that our design decision meant that we would require a data manager object that could “talk” to the various databases using SQL Pass-Through (SPT) and ODBC.
While it might have been sexier to opt for OLEDB, we could not be certain that all of our data sources would have an OLEDB provider (especially since we might have to deal with older, legacy, systems). More importantly, since OLEDB only produces ActiveX Data objects, not VFP cursors, there was little benefit in using it anyway because we were going to be building the components in VFP. We now drew our first (logical) model for the system:

The physical design
This model was easy to draw, but harder to build. In order to implement it we started by modeling the various real world entities that we knew would be required in the application. Since this was an Insurance application these included things like ‘Quotes’, ‘Policies’, ‘Investment Funds’ and so on. The idea was that each entity would be responsible for managing its own data set and the generic entity root class included all the necessary functionality to retrieve and save data sets. Code in the concrete classes augmented and specialized this core functionality.
The data sets were defined in local VFP tables, which meant that as the project evolved and the data structures inevitably had to be modified, we didn’t have to change any of our code. All we had to do was modify the metadata which consisted of three tables. One for the entities, one for the actual cursors used in the dataset and a link table to relate individual cursors to an entity. Of course, the same physical cursor could be used by several different entities, either alone, or in combination with others.
Two further supporting tables were required. The first contained the detailed cursor definitions and provided all the information required for the entity to build the SQL statement which would be used to retrieve data from the database. Note that while it defined the fields, tables and joins required to build the cursor it did not actually specify a data source. The information required to connect to the various back ends was stored in the second supporting table.
So we finally had a working model for our application. The functionality would be contained in the entities which would have all the necessary information to allow them to connect to and communicate with a back end database. Now all we had to do was to define the public interface for the entities.
Defining the Interface
Rather than exposing the individual entities directly to the outside world we implemented a façade pattern using a new class. This class provided the entry point into the application and hid the complexity of dealing with the sub system of individual entities. Named ‘InsLink’ (for Insurance Link Object) it was defined so that could be built as a DLL. Its public interface turned out to be very simple indeed. In fact there were only two exposed methods needed.
The first method was used to retrieve a data set from the back end and return it as an XML data stream – this was GetEntity(). The second accepted an XML data stream and saved the content to the appropriate tables in the database – this was SaveEntity(). It returned the completion status of the save request to the front end. The calling prototype for these methods was identical:
-
GETENTITY( Entity Name, Condition (string), Connection To Use, User Id )
-
SAVENTITY( Entity Name, XML data (string), Connection To Use, User Id )
So far so good, but what about the Automation aspects? Excel was to be used to handle the (very complex) calculations involved in generating Quotations, Forecasts and Proposals. The problem was that several different spreadsheets were involved and each had different requirements and returned different things. Our application had to collect the data from the user (via the Front End), package up that data, pass it to Excel and finally retrieve and unpack the results. However, we did not want our application to have intimate detailed knowledge about the inner working of all of these spreadsheets. Further investigation revealed that we also had to interact with Word to produce various documents. For reasons too complex to go into here, these had been set up as bookmarked documents rather than templates. The requirements for the Word automation included:
-
Replacing part of a bookmark
-
Replacing an entire bookmark
-
Selecting one or more of multiple bookmarks
-
Deleting unused bookmarks
So the big question was, how could we reconcile all these requirements? We finally realized that we were worrying about implementation again, not interface! Once we recognized that it was not really our problem, we realized that all we had to do was to define an interface that all automation objects, whether Word Documents or Excel Spreadsheets, could adhere to. The result was the addition of two VBA functions to all documents and spreadsheets:
The server-specific functionality was provided by these functions and this now meant that the only knowledge required by our application was the details of the interface! A new set of entities were designed to handle the automation requirements – although the basic functionality was very similar to that of the data handling entities. To accommodate these new entities we merely extended the public interface of the InsLink class to include a third exposed method (“CalcEntity”) that was used to initiate an automation process. The calling prototype for this method was, quite deliberately, made very similar to our GetEntity and SaveEntity methods, and it returned whatever the automation server passed back, thus:
uRetVal = oInsLink.CalcEntity( < Entity Name >, <XML Data (string) >, < Connection > ).
We had, at last, managed to encapsulate all of our key processes. The second, physical model, was a bit different than original logical model:

It took us about eight weeks to build our first working DLL based on this model. Our client wanted to see the DLL in action. So we prepared a little demo for him that would allow insurance agents to log in to the web site and access the appropriate products. The code looked something like this:
oInsLink = CREATEOBJECT( ‘Inslink.xInsLink’ )
oInslink.GetEntity( 'vflogin', 'agent01, agent01', 'products', 29 )
It returned an XML string that contained a list of products that agent01 had access to and displayed them on the web page, like this:

Needless to say, the client was not overly impressed! They needed something that could be demonstrated to potential investors, users and other interested parties. But to build the full web interface was going to take a significant amount of time anyway, and it was needed “RIGHT NOW!”
Does this sound familiar? Even if the web forms could have been ready much quicker than anticipated (which was not our problem fortunately), the requirement for something that was immediately demonstrable was still a problem. By this time though, we had gleaned enough information so that we actually had some idea of what this application was meant to do! So we finally did what we would have done in the first place if the clients had been able to be more specific about their business requirements: we built a working prototype of the entire application that could be run on a stand-alone laptop machine.
The Prototype
Now, here is the moral of the story and the point of this article. We already had a functioning DLL. Because we had rigorously programmed to interface rather than implementation, all we did to create a working prototype was to create a form class that had the same public interface as our DLL class. We simply replaced the DLL with our new form class and built a working VFP prototype in less than a week.
Compare Figure 5 with the physical design (Figure 3) and you will see exactly what we did. No change in functionality was required in order to convert our DLL to a working VFP prototype. All we had to do was swap one class (Inslink) for another (the Inslink Form class). Everything continued to work because the two classes shared the same public interface.
Conclusion
The project which we have outlined in this paper really happened, just as described. It brought home to us, in a very specific and real fashion not only the importance of programming to interface, but also just how much time and effort it really can save you.