Law of Demeter: Difference between revisions
No edit summary |
No edit summary |
||
| (One intermediate revision by the same user not shown) | |||
| Line 10: | Line 10: | ||
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 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 | == Application == | ||
Violations of the Law of Demeter can manifest as the following code smells: | Violations of the Law of Demeter can manifest as the following code smells: | ||
| Line 18: | Line 18: | ||
* '''Shotgun Surgery:''' Changes in one part of the dependency chain trigger modifications in many other parts of the code. | * '''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 | 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. | * '''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. | * '''Inline Classes:''' Simplify by removing intermediate classes that add unnecessary hops in the dependency chain. | ||
| Line 49: | Line 49: | ||
=== Demeter’s Demon === | === Demeter’s Demon === | ||
The Law of Demeter | 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: | To mitigate this: | ||
| Line 56: | Line 56: | ||
* Ensure system boundaries encapsulate their dependencies, keeping internal details hidden. | * 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. | |||
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:
- Data masquerading as objects: Chaining is harmless when dealing with objects that represent pure data without encapsulating complex behaviors.
- 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.