Grady Booch in "Object Oriented Analysis and Design":
"The idea of cohesion also comes from structured design. Simply stated, cohesion
measures the degree of connectivity among the elements of a single module (and
for object-oriented design, a single class or object). The least desirable form of
cohesion is coincidental cohesion, in which entirely unrelated abstractions are
thrown into the same class or module. For example, consider a class comprising
the abstractions of dogs and spacecraft, whose behaviors are quite unrelated. The
most desirable form of cohesion is functional cohesion, in which the elements of
a class or module all work together to provide some well-bounded behavior.
Thus, the class Dog is functionally cohesive if its semantics embrace the behavior
of a dog, the whole dog, and nothing but the dog."
Subsitute Dog with Customer in the above and it might be a bit clearer. So the goal is really just to aim for functional cohesion and to move away from coincidental cohesion as much as possible. Depending on your abstractions, this may be simple or could require some refactoring.
Note cohesion applies just as much to a "module" than to a single class, ie a group of classes working together. So in this case the Customer and Order classes still have decent cohesion because they have this strong relationshhip, customers create orders, orders belong to customers.
Martin Fowler says he'd be more comfortable calling it the "Suggestion of Demeter" (see the article Mocks aren't stubs):
"Mockist testers do talk more about avoiding 'train wrecks' - method chains of style of getThis().getThat().getTheOther(). Avoiding method chains is also known as following the Law of Demeter. While method chains are a smell, the opposite problem of middle men objects bloated with forwarding methods is also a smell. (I've always felt I'd be more comfortable with the Law of Demeter if it were called the Suggestion of Demeter .)"
That sums up nicely where I'm coming from: it is perfectly acceptable and often necessary to have a lower level of cohesion than the strict adherence to the "law" might require. Avoid coincidental cohesion and aim for functional cohesion, but don't get hung up on tweaking where needed to fit in more naturally with your design abstraction.
- Is Demeter unrealistic in any server/client scenario?
I think you answered your own question here. How is REST
in this manner different than SOAP
or XML-RPC
in this regard?
The point of REST
is not to provide super-loose coupling, but the following:
- Provide a identifier which accurately describes the resource being requested.
- Provide services which behave as expected
GET
requests are idempotent, PUT
updates records, POST
creates, DELETE
deletes
- Minimize state being stored on the server
- Tear down unnecessary complexity
There are cases where REST
isn't the best answer, but REST
works remarkably well in general.
Best Solution
First, the Law of Demeter, like most rules of programming, is more of a principle or guideline and there are occasions when the principle doesn't apply. That being said, the Law of Demeter doesn't really apply to Passive View because the reason for the law isn't a problem in this case.
The Law of Demeter is trying to prevent dependency chaining such as:
Obviously if objectB's implementation changes to use objectD instead then it will break objectA's dependency and cause a compilation error. If taken to an extreme you wind up doing shotgun surgery any time the chain is disturbed by an implementation change.
In the case of Passive View
So the example you gave would normally be implemented:
While the view would be something like:
Hope this clarifies things a bit.