1

So i have this code:

Public class Worker{
   private String gender;
   ...
   public Boolean isMale(){
      return gender=="Male";
   }
}

Public class Business{
   private Vector<Worker> vWorkers;
   ...
   public void showMaleWorkers(){
      for(Integer I=0; I<vWorkers.size();I++){
         if(vWorkers.elementAt(I).isMale()){
         ...
         }
      }
   }
}

Is the "if" breaking the law of demeter and if yes how could I solve it?

Tegu
  • 11
  • 1
  • Does this answer your question? [Law of Demeter with data model objects](https://stackoverflow.com/questions/26021140/law-of-demeter-with-data-model-objects) – Amadan Apr 08 '22 at 03:09
  • Technically, by the strict definition, it does, but conceptually it does not. It is silly to expect a `Vector` to know whether its elements are male or not. See "object vs data structure" distinction in the linked question's answer. – Amadan Apr 08 '22 at 03:11
  • @Amadan The distinction between "object vs data structure" in this context is a silly one. LoD is basically a rule *against* data structures. Saying that the LoD shouldn't apply to data structures is like saying the speed limit should not apply to cars that can go too fast. – Robert Bräutigam Apr 08 '22 at 07:13
  • @RobertBräutigam The fact is Java is not functional (or at least didn't start out that way and still has non-functional corners, as you observe). If `vWorkers` was an array instead of a `Vector`, the equivalent `vWorkers[I].isMale()` does not make a method call. There is no way to pass a callback to an array so that it can remain ignorant. Semantically there is no relevant difference between a `Vector` and an array. "The Paperboy, The Wallet, and The Law Of Demeter", AFAIK one of the influential publications on LoD, literally has a section titled "Sometimes Objects Are Just Containers". – Amadan Apr 08 '22 at 08:01
  • @Amadan I agree Java is not a functional language, it'll never be, since side-effects are allowed. Arguing that accessing array elements is not a method call is splitting hairs. Technically you're right. But in the context of LoD and OO, everything is supposed to be an object, which interact by "sending messages". Yes, Java is not even a completely object-oriented language. But these concepts apply anyway, regardless of technical implementation. Your cited paper lists "collections" as a good/necessary place to ignore LoD. I just demonstrated below it's not. – Robert Bräutigam Apr 08 '22 at 08:44

1 Answers1

1

It does. Both technically and conceptually.

It's not your code though. The culprit is the Vector which gives out internal state, instead of thinking ahead and implementing behavior.

The behavior in the vector's domain that it should implement for us would be "iterating" and "filtering". Something like this:

public void showMaleWorkers() {
   vWorkers
      .filter(_.isMale())
      .forEach(...);
}

This does not violate LoD while doing the exact same thing. At no point are we calling methods on things that we don't have access to directly. This is sometimes called "functional style", because filter() and map() etc. were first prevalent in functional languages. Curiously this is actually more object-oriented too.

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