Saturday, February 21, 2009

What Is Encapsulation? Part II: A Library That Does Nothing Is Nothing

OO design is built on several layers of encapsulation. You combine statements and encapsulate them in a method. You then combine methods and encapsulate them in a class. The next layer is a component, then a library, and finally the system itself.

Each layer should encapsulate more and more details. It should only expose the absolute essentials to the next layer. A library should therefore encapsulate all (or nearly all) of its details behind a well-defined, well-documented, simple, public API. A library that doesn’t encapsulate its details isn’t a library. At best it is simply shared code, at worst it is a disaster waiting to happen.

I have lately seen libraries that contain nothing but interfaces and classes with only data (essentially data structures). Usually these libraries come in pairs. One provides the public well defined API, and the other provides the implementation. This makes the two co-dependent on each other. They should both be thought of as one cohesive library.

There are good uses of this pattern. JDBC for example provides an interface library that is part of a specification. Multiple vendors provide their own implementations. Client code uses only the interfaces and the classes defined by the spec. This allows code that uses JDBC to stay independent of each vendor.

In general both the API and implementation should be a single cohesive library. This will allow the code to evolve together as a single unit, and be easier to change, deploy, and manage.

That isn’t to say libraries shouldn’t use interfaces. One could effectively argue for exposing all functionality via an interface. I think that is overkill. Still, using interfaces to expose most functionality is certainly a good idea, but put those interfaces in the same library as the implementation unless there is a specific technical reason why they can’t be deployed together. Even then both should be thought of as a single library forced apart by circumstances.

A while back I had an unpleasant experience with Charter Communications. They would schedule an appointment to install cable, but nobody would show up. This happened 5 times in a row before I gave up and moved to another provider.

The core of the problem is that the customer center is a completely separate department from the service center that did the installations. Some information was shared, but there were no real direct lines of communication. Everyone I talked to on the phone tried to be helpful, but they were limited in what they could do.

Here loose coupling worked against them. The service department implemented the requests gathered from the customers by the customer service department. There is a natural cohesion there, and decoupling them made it hard to provide adequate service to their customers.

In software terms, the customer service library contains the interface for making requests (such as an installation), and contains data used by both the customer and the service library. The service library implemented the interfaces, and consumed the data to do the actual work.

Suppose the service library needs to be modified to provide additional information or provide better interaction with the customer for some edge cases. It would be difficult to do since the customer service is in a different library with its own release cycle, evolution, and possibly entirely different development team. It’s likely one or both of two things will happen. First, users will be allowed to bypass the customer service library and use the service library directly. Second, the service library just won’t provide that behavior, or won’t do an adequate job. Neither option is appealing.

Loose coupling is a good trait to have, but only when it is combined with high cohesion. Separating a cohesive unit into two parts will at best force both parts to evolve together making the separation between them artificial. At worst it will allow the 2 to diverge making it impossible to add new features with out significant effort. It’s true with departments in a large company and its true with software libraries.


Blog Directory Listing

No comments:

Post a Comment