Jump to content

Law of Demeter: Difference between revisions

From Knowledge Base
No edit summary
No edit summary
 
Line 58: Line 58:
=== Disadvantages ===
=== Disadvantages ===
The Law of Demeter requires additional wrapper methods to avoid speaking to strangers, which often results in many parameters being passed. At the class level, this can lead to wide interfaces, as helper methods are necessary to prevent deep object nesting. This can conflict with principles like the Interface Segregation Principle, Single Responsibility Principle, and Separation of Concerns. Furthermore, adhering to LoD can slightly impact performance and increase memory usage.
The Law of Demeter requires additional wrapper methods to avoid speaking to strangers, which often results in many parameters being passed. At the class level, this can lead to wide interfaces, as helper methods are necessary to prevent deep object nesting. This can conflict with principles like the Interface Segregation Principle, Single Responsibility Principle, and Separation of Concerns. Furthermore, adhering to LoD can slightly impact performance and increase memory usage.
== End Notes ==
While the Law of Demeter provides valuable guidance, treat it as a heuristic rather than an absolute rule. Focus on designing systems with minimal public dependencies, as they have the most significant impact on modularity and maintainability.

Latest revision as of 07:18, 20 January 2025

Law of Demeter (Principle of Least Knowledge)

The Law of Demeter, also called the Principle of Least Knowledge, is a design guideline for developing software, particularly in object-oriented programming. It aims to reduce dependencies between components, enhancing modularity and maintainability. The core idea is to limit how much a given piece of code "knows" about the structure or properties of other parts of the system.

The name "Demeter" originates from the Greek goddess of harvest, grains, and fertility, reflecting an annual celebration in ancient Rome, who "rebranded" her to the goddess Ceres. However, in software development, its focus is on reducing dependency chains and improving code quality.

Application

Violations of the Law of Demeter can manifest as the following code smells:

  • Feature Envy: Methods that access multiple layers of a dependency chain.
  • Shotgun Surgery: Changes in one part of the dependency chain trigger modifications in many other parts of the code.

To adhere to the Law of Demeter, consider:

  • Dependency Injection: Provide direct access to required dependencies instead of accessing them indirectly.
  • Move Methods: Shift methods that rely on deep dependencies closer to the owner of those dependencies.
  • Inline Classes: Simplify by removing intermediate classes that add unnecessary hops in the dependency chain.

Critics and Considerations

"What" and "Why" of the Law of Demeter

The Law of Demeter is particularly relevant in object-oriented design, where chaining multiple method calls, such as `a.b().c()`, is considered poor design. Such chaining increases coupling, making the code harder to maintain and extend. By contrast, adhering to this principle can:

  • Reduce the complexity of dependency chains.
  • Simplify the understanding of what a function does and the objects it operates on.
  • Minimize cascading changes across indirect dependencies.

However, critics argue that following the law strictly can lead to overly complex code and unnecessary abstractions. For instance, splitting a straightforward expression like `a.b().c()` into a dedicated method on `a` may introduce additional coupling, contrary to the principle's intent.

When is Chaining Acceptable?

There are scenarios where chaining is benign or even desirable:

  1. Data masquerading as objects: Chaining is harmless when dealing with objects that represent pure data without encapsulating complex behaviors.
  2. Expected chaining between ADTs or objects: Public dependencies between modules can sometimes be legitimate and unavoidable.

Instead of outright banning chaining, evaluate whether the dependency is public or private. Public dependencies are more prone to causing issues, while private dependencies remain encapsulated and easier to manage.

Design Errors to Avoid

A common misstep is introducing public methods that expose internal dependencies unnecessarily. For example, adding a getter for an object within a class just to access its properties can lead to coupling issues. Instead, consider:

  • Whether the dependency should remain private.
  • If a new public method aligns with the class's responsibilities.

Demeter’s Demon

The Law of Demeter can be crucial at system boundaries. If a system boundary (e.g., an interface) has public dependencies, those dependencies also become system boundaries. External users may rely on these dependencies, making future changes challenging without risking breaking compatibility.

To mitigate this:

  • Avoid exposing internal types (e.g., a red-black tree's `Node` type) in public interfaces.
  • Ensure system boundaries encapsulate their dependencies, keeping internal details hidden.

Disadvantages

The Law of Demeter requires additional wrapper methods to avoid speaking to strangers, which often results in many parameters being passed. At the class level, this can lead to wide interfaces, as helper methods are necessary to prevent deep object nesting. This can conflict with principles like the Interface Segregation Principle, Single Responsibility Principle, and Separation of Concerns. Furthermore, adhering to LoD can slightly impact performance and increase memory usage.