Reputation: 62244
Say you have something like the following (sadly, I'm not allowed to post the original code):
public void foo() {
MyObject obj = getMyObject();
bar(obj);
}
public void bar(MyObject obj) {
Type type = new Type(obj.getOtherObject());
}
foo
calls bar
, passes in obj
. But instead of using obj
,it calls a getter on it to retrieve the needed information. Does this violate the Law Of Demeter?
Would it be better to write something like this:
public void foo() {
MyObject obj = getMyObject();
bar(obj.getOtherObject());
}
public void bar(MyOtherObject otherObj) {
Type type = new Type(otherObj);
}
Upvotes: 1
Views: 167
Reputation: 64517
Indeed according to the wiki on the Law of Demeter:
The fundamental notion is that a given object should assume as little as possible about the structure or properties of anything else...
Your bar
assumes that a given MyObject
(a concrete type so strongly coupled, again against LoD) has a method called getOtherObject
, so your proposed solution sorts the assumption and moves the code closer to adhering to LoD. You can go even further and instead provide the type that bar
wants:
bar(new Type(obj.getOtherObject());
Depending on your language, can you not pass an interface/contract instead of a solid type? This would turn the strong coupling into a looser coupling.
Of course, if this is all internal to a given object then perhaps it isn't breaking LoD because it's a "close friend":
- Each unit should have only limited knowledge about other units: only units "closely" related to the current unit.
- Each unit should only talk to its friends; don't talk to strangers.
- Only talk to your immediate friends.
In OO I think your original code is breaking LoD based on this argument:
...an object A can request a service (call a method) of an object instance B, but object A cannot "reach through" object B to access yet another object, C, to request its services. Doing so would mean that object A implicitly requires greater knowledge of object B's internal structure.
To me it seems that you are using obj
in order to call getOtherObj
. Your proposed code is a potential solution.
Upvotes: 2