Reduce Java object navigation chains so collaborators expose useful behavior instead of leaking internal structure.
The Law of Demeter (LoD), also known as the Principle of Least Knowledge, is a fundamental guideline in object-oriented design that emphasizes minimal knowledge sharing between software components. This principle suggests that a given object should only communicate with its immediate neighbors, thereby reducing dependencies and promoting encapsulation. By adhering to the Law of Demeter, developers can create more robust, maintainable, and flexible Java applications.
The Law of Demeter can be succinctly described as: “Only talk to your immediate friends.” This means that a method of an object should only call methods belonging to:
This principle discourages the practice of method chaining, where an object calls methods on objects returned by other methods, leading to a “train wreck” of method calls. Such practices increase coupling and make the code more fragile and difficult to maintain.
Adhering to the Law of Demeter reduces coupling between classes, which is a measure of how closely connected different classes or modules are. Lower coupling is desirable because it makes the system more modular and easier to modify. Encapsulation, the bundling of data with the methods that operate on that data, is also enhanced by limiting the exposure of an object’s internal structure.
Consider the following Java code snippet that violates the Law of Demeter through method chaining:
1public class Car {
2 private Engine engine;
3
4 public Engine getEngine() {
5 return engine;
6 }
7}
8
9public class Engine {
10 private FuelInjector fuelInjector;
11
12 public FuelInjector getFuelInjector() {
13 return fuelInjector;
14 }
15}
16
17public class FuelInjector {
18 public void injectFuel() {
19 System.out.println("Fuel injected.");
20 }
21}
22
23public class Driver {
24 public void startCar(Car car) {
25 car.getEngine().getFuelInjector().injectFuel();
26 }
27}
In this example, the Driver class is directly accessing the FuelInjector through a chain of method calls, violating the Law of Demeter.
To adhere to the Law of Demeter, refactor the code to encapsulate the behavior within the Car class:
1public class Car {
2 private Engine engine;
3
4 public void start() {
5 engine.injectFuel();
6 }
7}
8
9public class Engine {
10 private FuelInjector fuelInjector;
11
12 public void injectFuel() {
13 fuelInjector.injectFuel();
14 }
15}
16
17public class Driver {
18 public void startCar(Car car) {
19 car.start();
20 }
21}
In this refactored version, the Driver class interacts only with the Car object, which internally manages its components, adhering to the Law of Demeter.
By following the Law of Demeter, developers can achieve:
Several design patterns inherently support the principles of the Law of Demeter by promoting loose coupling and encapsulation:
The Law of Demeter is a crucial principle in object-oriented design that fosters loose coupling and strong encapsulation. By limiting the interactions between objects to their immediate neighbors, developers can create systems that are easier to maintain, more robust, and flexible. Understanding and applying this principle, alongside design patterns that promote these qualities, is essential for building high-quality Java applications.
Consider how the Law of Demeter can be applied to your current projects. Are there areas where method chaining could be reduced? How might encapsulation be improved to enhance maintainability and robustness?