Back Side Of An Interface

From http://www.artima.com/weblogs/viewpost.jsp?thread=147355 -

Interfaces and "calling out the back". Another thing that all software engineers - and many other kinds of engineers - seem to agree about is the separation of interface and implementation. Of course, that's closely related to encapsulation. I hope we all agree that the data members of an object should be private. So the interface of the object is defined by the methods it provides. Right? Well, up to a point.

Electrical engineers work with boxes. What comes out of the box is the interface. What's inside the box is the implementation. Here's a box. Is this its interface?

No, not quite. It has a back as well as a front, and here's the back. The interface consists of both the front, with the user controls, and the back, with all the wires going to the rest of the world.

How does this relate to objects? The public methods of an object are just the front view: the user controls. The interface consists of the public methods provided to users and the methods of other objects that the object calls. But in design we tend to ignore the back and worry about the front only. UML encourages this, by the way.

There are loads and loads of languages that follow this model, where it is known as required interfaces, outgoing interfaces, etc. etc. Look at ArchitectureDescriptionLanguages, ConfigurationProgramming?, ModuleInterconnectionLanguage?s, and many other terms for the same thing. Specific examples are the MesaLanguage from ther 70s, the ConicLanguage? from the 80s, the DarwinLanguage? from the 90s, NescLanguage?, currently used to program TinyOs? for small embedded systems and many, many others.

The idea that "in design we tend to ignore the back and worry about the front only" is not correct. There is a long history of languages and design approaches that do worry about the back. It's just enterprise IT (as usual) that fails to pick up the good ideas.

Please expand upon what the "back side" of an interface/object might be. I do not see how an encapsulated object has a direction to imply front or back.

Think in terms of API vs SPI. The API is the front-side of the object: it provides methods that clients call to perform some functionality. The SPI is the back-side: it provides methods that clients implement to expose their functionality.

This is also why one should be very careful with interface design (http://www.artima.com/weblogs/viewpost.jsp?thread=142428). The more convenience methods in an interface, the easier it is to use as an API. Conversely, the harder it is to implement as an SPI. JavaLanguage usually solves this problem by providing an interface as the API and a corresponding AdapterPattern AbstractBaseClass to implement as an SPI. However, you lose all control over who implements your SPIs, and generally can't make the same sort of runtime guarantees to the clients of the API. NetBeans solves the problem by providing interfaces as SPIs, then aggregating SPI objects into an internal NetBeans class that implements the API. They gain more control this way, and it's easier to deal with their SPIs, but you lose testability and the ability to create MockObjects. -- JonathanTang

What is meant by the term "SPI" and how does it differ from an "API"?

SPI stands for "ServiceProgrammingInterface?". It doesn't really differ from an ApplicationProgrammingInterface (API). It's just an API lower down the software stack that the implementor of a plug-in component must adhere to. The term SPI comes from the Microsoft world. The implicit assumption is that application programmers -- those who use an API -- are a bit thick, and only the more skilled developers should be allowed to use an SPI.

Also, typically SPI providers are implementing an interface, while API users are calling an interface. -- JonathanTang

Not in most object-oriented APIs.

Is the difference that an API is targeted to external users while an SPI is targeted at internal users? The difference I am trying to imply would be that an API would need to be more robust, while an SPI could rely on quite a bit of shared knowledge. Thanks for the help so far, I'm just a little slow to grasp the idea being discussed!

It may be helpful to look at some examples:

Netbeans Project module:

http://www.netbeans.org/download/dev/javadoc/org-netbeans-modules-projectapi/overview-summary.html

The API consists of classes and methods that other plugins call to get information about and manipulate projects. The SPI consists of interfaces and abstract classes that project plugins implement to provide new project types.

Winsock/Winsock LSPs:

http://www.microsoft.com/msj/0599/LayeredService/LayeredService.aspx

Winsock is an API; it provides functions that applications call when they want to access the network. Winsock Layered Service Providers implement an SPI to "hook into" the connection process, allowing them to manipulate all incoming and outgoing connections. Many personal firewalls are built upon the Winsock SPI.

-- JonathanTang

Think of a mouse. It has two interfaces. One is the mouse ball (or optical tracking), buttons, wheel, etc. The other is the USB or RS-232 interface by which the mouse is connected to the rest of the system. To the user, the buttons/wheel are the "front" interface and the USB connection is the "back" interface. Is it valid to say that, to the device driver writer, the USB connection is the "front" interface and the ball/buttons/wheel are the "back" interface? -- MikeSmith


I disagree. There are tools that do a wonderful job of supporting this idiom. The idiom has been in use since the late 1970s. I'm writing some code for the embedded TinyOS operating system using the nesC language that supports this idiom (although not as well as other languages do). Other software systems that use these idioms are used in millions of TV sets, to control power stations and to build multimedia systems such as the video and audio players in the GNOME desktop. For some reason, enterprise IT ignores these ideas, but they seem to ignore most good programming ideas from about 1971 onwards and pick most of the bad ones, so that's not too surprising. We have to sneak them in by the back door, in disguised forms (MockObjects, DependencyInjection, etc. etc.).

Yes, context is everything! You could take an existing ArchitectureDescriptionLanguage and use it to combine Python components. Or you could use a language with a good model of component composition. But if you pick a language that has a conservative design (like Python) you get what you get.

If Tom is referring to interfaces exposed outside of a single executable element (for example, a program, library, or component), then I fully agree with his statement on lack of tool support. I am not even certain we have established the knowledge base to do a good job manually. Currently, version control of external interfaces is handled in an ad hoc manner by individual developers, resulting in forced rebuilds when new versions are released and inidvidual methods being overlayed with multiple operations (in order to avoid adding a new method and "breaking" the interface). Error handling is not well defined and often requires a man in the loop to process error queues. Starting and Stopping interfaces and being able to deal with interfaces that are not always available is not well understood and often requires a man in the loop to gracefully stop and restart. Synchronization of data between systems and systesm of record are not fully understood and again often require a man in the loop to reconcile. I am not sure if this was intended, but these issues certainly resonate with me. --WayneMack


I'd like to summarize Toms argument to check if I understand it right:

The front-side is the "normal" interface, i.e. the public methods (strictly the protocol to use it also belongs to this, but this is mostly captured in documentation and maybe assertions). There are are a lot of tools, that let you browse libraries and code assist helps you finding and calling these methods on objects implementing these interface.

The back-side is that part of an implementation of this interface in a framework or library, that depends on other libraries/classes to do so. The implementor may have its own plug-ins or provide only an abstraction of a protocol. And now comes the main point: There are multiple idioms to provide these plugin-points and there is no tools support to find them much less verify or check against them. All that can be done is to present them as an interface marked somehow as "SPI". But this already forces a specific way to specify the back-side. But we would like to use e.g. StrategyPattern, TemplateMethode? or CallBack? and let the tool show these points to us, together with the components plugging into them.

-- GunnarZarncke


FebruaryZeroSix

CategoryInterface


EditText of this page (last edited October 11, 2006) or FindPage with title or text search