Friday, January 06, 2006

Martin Fowler wrote about using the implicit interface formed from the public members of classes as an actual interface. The idea is that one can substitute another class that implements this implicit interface, and pass it to code that, being poorly factored, or whose source code is unavailable or unmodifiable, would use the new class in lieu of the old.

The problem I have with the idea is that classes that don't already have an appropriate abstract ancestor or implement a suitable interface often have more than just a public interface. Suppose we have two types, T and U. Let T have two members, a() and b(), where a() is public and b() has package (Java) or internal (C#) visibility. Let U have one member, c(T). Let us further suppose that U.c(T) invokes T.b() as part of its implementation.

Let us finally say that some other class S with a member S.d(T) exists which calls U.c(T) on the passed-in T.

With this example, it's impossible to implement just the public interface of T on another class, and pass it to S.d(T). The reason is that S.d(T) calls U.c(T), and U.c(T) expects T.b() to exist. This means that our public interface on T must include package or internal methods, and that would expose implementation details. It might even be a security risk, since some new implementation of T could delegate calls to T.a() to a private member T, but intercept calls to T.b() and discard them.