3
class MyCollection {

   Items menuItems;
    ...
   public Iterator createIterator() {
      return new Iterator(menuItems);
   }

}

class Client {

    public someMethod() {
        Iterator iterator = collection.createIterator();
        while(iterator.hasNext()) { //doSomething } 
        // Client is calling iterator's method directly
    }
}

above is a simple iterator pattern.

I wonder does Client violates the principle of least knowledge.

Is it inevitable to violate the principle in iterator pattern?

jaco0646
  • 15,303
  • 7
  • 59
  • 83
Jerry
  • 399
  • 1
  • 2
  • 17

3 Answers3

0

Technically the Client does violate the Law as the object(iterator) is neither an instance variable nor a passed argument. However a Collection being a pure data structure they are exempt from this law Law of Demeter with data model objects

  • *If* you want to do Object-Orientation, you *have to* deal with the Law of Demeter. There is no such thing as "Data Object" or "DTO" in Object-Orientation. That does not mean you absolutely always have to follow it, but there are no categoric exemptions. You *should* always try to follow it. – Robert Bräutigam Feb 20 '18 at 11:46
  • I know, it is still wrong. In the same book Uncle Bob also mentions that he does not consider the rules of Object-Orientation binding. I consider Uncle Bob a *mixed paradigm* developer, not an Object-Oriented developer. Which might be better or worse is of no consequence for this discussion, but it does mean that Uncle Bob's opinion comes from a different context. – Robert Bräutigam Feb 20 '18 at 12:54
0

The reason LoD exists is to avoid unnecessary coupling, which makes programs fragile.

The Law of Demeter says that a method f of a class C should only call the methods of these:

  1. C
  2. An object created by f
  3. An object passed as an argument to f
  4. An object held in an instance variable of C

Since someMethod() in Client creates the iterator with createIterator() (which is in many cases a polymorphic Factory method), it does not violate LoD. Condition #2 allows f to call methods of an object it creates.

Community
  • 1
  • 1
Fuhrmanator
  • 11,459
  • 6
  • 62
  • 111
0

Here is an Article on the Law of Demeter, that explains how and why you should follow it.

In short: The code you showed just stopped right before it violates the LoD.

You can use the iterator, since it is created for you. Any object created during your method, even indirectly, you can deal with. So createIterator() works, and you may access the Iterator object.

The Iterator.hasNext() also works for the same reason. It creates a boolean for you, which you may access then.

However, technically you may not touch any item you get back with Iterator.next(). Since those objects are not created for you, and you have no direct reference on them, touching those objects would actually constitute a violation of LoD.

Robert Bräutigam
  • 7,514
  • 1
  • 20
  • 38