How Big Is Your Object's Interface? The Answer Might Surprise You!

We have a Person object, eddie. Part of the responsibilities of a Person object is to operate a Car, accessible as eddie.getCar(). Cars are made of parts like Doors and Seats and an Engine. Starting a Car entails starting its Engine. So how would we start eddie's Engine?


eddie.getCar().getEngine().start();

This accomplishes the task, but we see a violation of the Law of Demeter in this code. We can see this quite plainly: look at all the dots! But what is this "law," and who passed it? I don't think Congress concerns itself with these matters (at least not yet). How bad can writing code like this really be?

To understand why we should follow Demeter, we have to see what happens when we don't. Our Person, eddie seems to have a very simple interface so far, a getCar() method. He just has that one method, but that method gives us back a Car with a getEngine() method. That method then gives us an Engine with a start() method. Each intermediate object has a simple interface, but the truth is that this is really all a single, complex interface we have to deal with. The interface of Person here includes the interfaces of all the things we need to use to make use of it. To start eddie's car, we need to know that he has a Car that has an Engine that we can start(). We've assumed the interfaces of these objects are all simple, but the truth is that a Car also has Doors and Seats and more. An Engine likely also has a larger interface for interacting with it and its components.

The expansive interface of our Person class through this chain breaks encapsulation, exposing things that are better kept hidden. For example, anyone who can get eddie's Car could also call the unlock() method on that Car. Because eddie's interface includes the full interface of his Car, we cannot stop anyone who knows eddie from doing this.

The Law of Demeter is also known as the Principle of Least Knowledge. It directs us to know as little as we need to get our job done. And the Law of Demeter has nothing to do with dots; it's all about types. By reaching through eddie and then through his Car, we are incorporating deep knowledge of the structure of multiple types directly into our implementation. If any of that knowledge, the effective interface of a Person, becomes outdated, our code breaks. The less we need to know, the simpler and less fragile our code can be.

When we realize that every type we require (both in and out) for our objects adds to the interface of those objects, we can be mindful of that interface and preserve encapsulation. We can raise the level of our code:


eddie.startCar();

Comments

Popular posts from this blog

The Timeline of Errors

Magic Numbers, Semantics, and Compiler Errors

Assuming Debugging