# Use the Bridge Pattern with Interfaces Interfaces allow you to use selected functionality of a class without needing to know the concrete type. An interface is perhaps the most powerful form of polymorphism. In Java, interfaces are a built-in type. In C++ interfaces are pure virtual base classes. In COM, interfaces appear as an array of function pointers. The Bridge/Impl pattern is a very effective way to simplify the use of interfaces. When you require someone else to implement an interface, such as a callback, you should oblige them to implement as few methods as possible. Keep the methods simple and their behavior unambiguous. When you provide interfaces for others to use, they want you to provide as many convenient services as possible. Users want extra methods with default arguments, and they want robust tolerance of special cases. Most interfaces eventually have both uses. How can you avoid this conflict in priorities? You need the Bridge pattern. Begin with the simplest methods necessary to define your functionality. For a ``Vector'' you might define methods to ``add'' another vector and to ``scale'' by a constant. These methods will constitute your implementation interface, called ``Impl'' for short. Next define a full-featured interface that has convenience methods like ``zero'' and ``copy.'' Most often, you want to derive the full-featured interface from the simple ``Impl'' interface, so that simple methods are still available. The extra methods can be coded by using only the methods in the ``Impl'' class. You can code these implementations once and for all in one place, the bridge class. In Java your bridge class might look like
public interface VectorImpl { public void scale(double factor); public void add(Vector anotherVector); } public interface Vector extends VectorImpl { public void zero(); public void copy(Vector anotherVector); } public class VectorBridge implements Vector { private VectorImpl _vectorImpl; public VectorBridge(VectorImpl vectorImpl) { _vectorImpl = vectorImpl; } public void scale(double factor) { _vectorImpl.scale(factor); } public void add(Vector anotherVector) { _vectorImpl.add(anotherVector); } public void zero() { _vectorImpl.scale(0.); } public void copy(Vector anotherVector) { this.zero(); _vectorImpl.add(anotherVector); } }Most of your code will export ``Vector'' interfaces, and you will require users to implement ``VectorImpl.'' ``VectorBridge'' makes a ``VectorImpl'' look like a full-featured ``Vector.'' In C++, you can follow the same style or you can abbreviate with an abstract class. (Some methods have implementations, and others do not.)
class Vector { public: virtual void scale(double factor) = 0; virtual void add(const Vector& anotherVector) = 0; virtual void zero() { this->scale(0.); } virtual void copy(const Vector& anotherVector) { this->zero(); this->add(anotherVector); } virtual ~Vector() {} };Now we have only one interface for a vector. The three preceding classes have been combined into one. Users can override the extra methods if they have a more efficient implementation. Otherwise, they get a usable default. On the other hand, if you need only the ``Impl'' methods, a user may unnecessarily optimize unused methods. You can code an identical abstract class in Java, but with a serious drawback. Java classes can implement any number of interfaces but can extend only one abstract class. Personally, I prefer to keep all implementation out of interfaces. There are good reasons for avoiding multiple inheritance of implementations. Nevertheless, the simplicity of adding default convenience methods is very tempting. Bill Harlan, 1999