Let's say I have a class SelectableEntity<T extends Entity>
which has three methods, select
, deselect
, isSelected
and count
.
To take a somewhat contrived example, let's say I'm building an emergency messaging application that allows me to message to residents during fires, floods and other natural disaster.
I can select multiple entities of different types (but all for the same reason). Let's say these entities are House
, Street
and Suburb
.
Now let's say I have a class called MessageRecipients
that contains a SelectableEntity<House>
, SelectableEntity<Street>
, SelectableEntity<Suburb>
.
There are two ways I could code this:
The first way is to create getters (i.e. houses
, streets
, suburbs
) and select / deselect recipients that way.: messageRecipients.streets.select(aStreet)
.
The other way would be to hide the fact that MessageRecipients
is using SelectableEntity
at all and simple create 'proxy' methods for each method on SelectableEntity
(i.e. selectHouse
, deselectHouse
, selectStreet
, etc).
The first method seems like it violates the Law of Demeter whereas the second method basically requires me to create a whole bunch of methods on MessageRecipients
that just directly invoke the relevant instance of SelectableEntity
(and requires a whole bunch of extra testing to ensure the correct methods are being invoked).
My question is, is the first example a standard example of a violation of the Law of Demeter and would it preferable to stomach all the duplication and verbosity and go down the second approach (a guess a follow question is what constitutes a valid reason to break the Law of Demeter, if anything)?
Note: The example I've given is made-up and I'm aware that it might break down in certain situations (i.e. streets and suburbs contain houses - if I add a street which has house XYZ and I call messageRecipients.houses().isSelect(houseXYZ)
it should return true). For the sake of this discussion that case should be ignored as it doesn't apply to the actual scenario I'm dealing with.