Then I would say The Law of Demeter has nothing to do with OO principles, and it has to be language-dependent coding style. PERIOD.
Unfortunately, it was defined in terms of OO, so arguing about that is somewhat futile.
But as with all methodologies, it could use some toning down in dramatic presentation. Nevertheless, it's an important design concept.
Regarding getters, they really are a mistake and side-effect of hammering SQL databases into enterprise beans. The alternate approach is commonly used:
class Account {
int getAmount();
void setAmount(int newAmount);
};
Account a = ...
int newValue = a.getAmount();
newValue += 100;
a.setAmount(newValue);Obviously, getters expose internal state. There is something known as amount, which is an intrinsic property of Account.
Instead, we do this:
class Account{
void deposit(int value);
};
Account a = ...
a.deposit(100);Trivial case, but we no longer know or care about how amount is represented. value would most likely be represented with a class as well.
"Ah, but I need to be able to access amount so I can print it":
class Account{
void printValue(OutputStream o);
}Since representation of amount no longer matters, it might be float, it might be value+currency, it might be coconuts, the above works - only Account knows how it's done.
"Ah, but I need to frobnicate the amount". Again:
interface Frobnicator {
int foo(int a);
}
class SeriousFrobnicator implements Frobnicator {
int foo(int a) {
return a + toAdd;
}
private int toAdd;
};
class Account {
void frobnicate(Frobnicator f) {
amount = f.foo(amount);
}
private int amount;
};
Account a = ..
a.frobnicate(new SeriousFrobnicator(100));Each of these examples doesn't access anything from outside, it uses only its own members, and is open to change.
One potential downside is that certain non-object types are passed as parameters (such as int), which goes against "pure" solution, but doesn't break it.
And eventually you end up with dependency injection and inversion of control, which is a proven way to scale projects. It's somewhat tedious to write (known issue with LoD as well) and it does require considerable number of various helper classes, but it achieves the important goal, namely keeping project loosely coupled.
In practice, recognizing well-designed code is trivial. But LoD might not be the most crucial part. While loose coupling generally is desirable, there can be too much of a good thing and there are several ways to achieve it.