How Big Is Your Object's Interface? The Answer Might Surprise You!
We have a
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
The expansive interface of our
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
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:
Person
object, eddie
. Part of the responsibilities of a Person
object is to operate a Car
, accessible as eddie.getCar()
. Car
s are made of parts like Door
s and Seat
s 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 Door
s and Seat
s 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
Post a Comment