# better dog.walk() # worse dog.legs().front().left().move() dog.legs().back().right().move() # etc.
There are two reasons why the second is worse. The first, not really directly LOD-related, is that your walk logic isn’t reusable, which is a problem in the case where there are multiple places in your codebase where a dog must walk.
The LOD-related reason why this code is bad is because it forces the current consumer to know that
DogLeg exists and how to operate it. The unspoken expectation here is that your consumer only knows about a
Dog, and that it can be made to move around, but how that
Dog moves around isn’t something the consumer cares about (that’s up to the
Dog to manage for themselves).
However, that is not necessarily the case for your other example.
User are both domain objects of which your consumer has public knowledge, then there’s no issue with asking them to handle a
User object directly.
The expectation here is that “the account refers to its owner” is part of the
Account interface, and therefore returning the owner (represented by a
User object) is fair game.
Dog interface is not expected to include “the dog has legs”, but rather “the dog is able to move around“, and the legs are just an implementation detail so the dog is able to fulfill its contract (i.e. moving around). The interface itself doesn’t specify the existence of legs, and therefore the consumer of
Dog shouldn’t be relying on the existence of legs.
In essence, a
DogLeg is considered a private implementation detail, whereas a
User (class) is publically known. This means that there’s significantly less issue with expecting your consumer to handle a
User than there is with expecting them to handle a
That being said, if
account.user() was actually an
AccountUser object which would also be considered a private implementation detail, then the same principle applies as it does for
This is what makes LOD so tricky to pinpoint. It’s not something that is objectively true based on your code alone, it hinges on subjective context and expectation of interfaces/contracts. By renaming the code, you change the reader’s implicit expectation, which can change whether something is considered an LOD violation.
Technically, it’s the same code. But what changes is our expectation of how acceptable it is to force a consumer to directly handler a
DogLeg vs forcing them to handle a