1

If I have an ArrayList of objects then any time I need to call any method on a member of the ArrayList I need to do it like this:

list.get(i).doSomething();

This looks suspiciously like a Law of Demeter violation. I can not see any way of getting around this. Is this fine or should I rethink how I do things like this. Is the ArrayList an object defined to ignore the Law of Demeter?

kabeersvohra
  • 1,049
  • 1
  • 14
  • 31
  • Could you explain how you see a Law of Demeter violation? – Matthew Jul 29 '16 at 13:33
  • Maybe describe more of what you want to do? I don't see an issue here, it's not like you're calling 10 getters on a row. – Tunaki Jul 29 '16 at 13:33
  • I realise this isn't a huge violation but it still seems like a code smell. It is a LoD violation because I am retrieving an object from the ArrayList and then calling a method on the retrieved object. Technically I should do something like list.callSomethingOn(i) to preserve the Law of Demeter but that seems wrong as well – kabeersvohra Jul 29 '16 at 13:38

2 Answers2

2

It is not a violation.

If you had a class

Class A {
    private B b1, b2, b3;

    ...

   private void method() {
       b1.doSomething();
       b2.doSomething();
       b3.doSomething();
   }
}

there is no violation. If we collect the instance of B into a List<B> you get

Class A {
    private List<B> listOfB;

    ...

   private void method() {
       listOfB.forEach(B::doSomething);
   }
}

Using an List<B> to hold the instances of B results in no tighter coupling between A and B.

bradimus
  • 2,472
  • 1
  • 16
  • 23
1

I don't really see a violation here.

The Law of Demeter, in concept, proposes that an entity only knows of its neighbors, not strangers, so if A needs something from C, it should talk to B to get it and not go any further.

I wouldn't exactly call a List a "neighbor" to apply to this concept. It's an object that manipulates a data structure which you can use throughout your program. Therefore, the Object that your list contains would be considered the B to your A.

If List was an actual entity defined in your program, you could be right in this case. It would make more sense to have your List have a method which calls for your Object to perform some logic (as you said in a comment, list.callSomethingOn(i)).

If this particular instance of List is central to your program's logic and you're adamant about satisfying the law, you could use a "Decorator" for the List which adds additional methods to work with the contained Objects

Zircon
  • 4,677
  • 15
  • 32