Inspired by this question, but hopefully not a duplicate.
I understand that the Law of Demeter is very useful in case of services interacting with other services, for example it's much easier to mock the other services in unit tests. What about services interacting with data models, though?
Let's say I have a hierarchy of immutable classes:
public final class Document {
private final List<Page> pages;
// Constructor, getter, ...
}
public final class Page {
private final List<Paragraph> paragraphs;
// Constructor, getter, ...
}
public final class Paragraph {
private final List<Line> lines;
// Constructor, getter, ...
}
Let's say I want to do something with certain lines in a document doc
:
public void doSomething(Document doc) {
for (Page page : doc.getPages()) {
for (Paragraph para : page.getParagraphs()) {
for (Line line : para.getLines()) {
if (someCondition(line)) {
someAction(line);
}
}
}
}
Now, as far as I understand, the above code doesn't obey the Law of Demeter.
However, I don't want to force the law at all cost and clutter the model (here, the Document
class) with tens of methods like:
public List<Line> filterWrtSomeCondition();
public List<Line> filterWrtSomeOtherCondition();
Or maybe there's a third way? I suspect that the Law of Demeter applies primarily to services interacting with other services. Is it a valid interpretation?