Search
Close this search box.

Using Interfaces – Design by Contract

An argument for Interface based design and programming
For software to survive in the ever-changing jungle of the production environment, it must have three distinct characteristics: reusability, maintainability, and extensibility.
Interface-based programming exists outside the world of COM. It is a programming discipline that is based on the separation of the public interface from implementation. It was pioneered in languages such as C++ and Smalltalk by software engineers who discovered that using distinct interfaces could make their software, especially large applications, easier to maintain and extend. The creators of Java saw the elegance of interface-based programming and consequently built support for it directly into their language.
Interfaces solve many problems associated with code reuse in object-oriented programming. This document will discuss what some of these problems are. In particular, when you program in a style consistent with classic OOP, a client can build inflexible dependencies on a class definition. These dependencies can make it difficult to maintain or extend the class without breaking the client. It becomes tedious or impossible to improve the code for an object over time. Certain problems are also associated with a popular OOP language feature known as implementation inheritance. This powerful but often misused feature is vulnerable to similar dependency problems, which compromise an application’s maintainability and extensibility. Since most 3GL languages support implementation inheritance, this document will discuss its strengths and limitations in order to address some of the problems that interface-base programming was created to solve.

Separating the Interface from the Implementation
Object composition offers another way to achieve reuse without the tendency toward tight coupling. Object composition is based on black-box reuse, in which implementation details of a class are never revealed to the client. Clients know only about an available set of requests (the what). Objects never expose internal details of the response (the how).
Black-box reuse is based on formal separation of interface and implementation. This means the interface becomes a first-class citizen. An interface is an independent data type that is defined on its own. This is an evolution of classic OOP, in which a public interface is defined within the context of a class definition.
At this point, you are probably thinking that this is all pretty vague. You’re asking yourself, “What exactly is an interface?” Unfortunately, it’s hard to provide a concise definition that conveys the key concepts of an entirely new way to write software. An interface can be described in many ways. You can get up to speed pretty quickly on the syntax for defining, implementing, and using interfaces. However, the implications that interfaces have on software design are much harder for the average programmer to embrace. Learning how to design with interfaces usually takes months or years.
At its most basic level, an interface is a set of public method signatures. It defines the calling syntax for a set of logically related client requests. However, while an interface defines method signatures, it cannot include any implementation or data properties. By providing a layer of indirection, an interface decouples a class from the clients that use it. This means an interface must be implemented by one or more classes in order to be useful. Once an interface has been implemented by a class, a client can create an object from the class and communicate with it through an interface reference.
You can use an interface to create an object reference but not the object itself. This makes sense because an object requires data properties and method implementations that cannot be supplied by an interface. Because it is not a creatable entity, an interface is an abstract data type. Objects can be instantiated only from creatable classes known as a concrete data types.
From a design standpoint, an interface is a contract. A class that implements an interface guarantees the objects it serves up will support a certain type of behavior. More specifically, a class must supply an implementation for each method defined by the interface. When communicating with an object through an interface reference, a client can be sure the object will supply a reasonable response to each method defined in the interface.
More than one class can implement the same interface. An interface defines the exact calling syntax and the loose semantics for each method. These loose semantics give each class author some freedom in determining the appropriate object behavior for each method. For instance, if the IDatabase interface defines a method named ExecuteSql(string commandText), different class authors can supply different responses to the same request, as long as each somehow reinforces the concept of running a sql statement. The OracleDatabaseConnector class can implement ExecuteSql() in a different way than either MSSqlDatabaseConnector or SybaseDatabaseConnector. This means that interfaces provide the opportunity for polymorphism. Interfaces are like implementation inheritance in the sense that they let you build applications composed of plug-compatible objects. However, interfaces provide plug-compatibility without the risk of the tight coupling that can occur with implementation inheritance and white-box reuse.

Note that this is an example only I am not sure I could ever justify doing this or argue that this is a good thing unless your are forced into it. I felt compelled to implement this due to usage restrictions in a corporate environment. In an effort to foster reuse (topic for another time… How and when to write for reuse) and comply with some misinterpreted security policies a wrapper was written around .Net native Data Access to “Protect” developers from themselves and to hide database connection strings from developers at runtime in the IDE. DON’T ASK HOW that’s a story for another day.

This article is part of the GWB Archives. Original Author: Evan Linden

Related Posts