问题
I have been building a RTS to improve my Java skills. I have been reading a lot about the Law of Demeter because I want to keep my code clean but I'm still quite confused! At the moment I have some code like this in the view to show how many of a certain ship there are in a fleet on the selected planet:
int numberOfFrigates = model.getSelectedPlanet().getFleet().getNumberOfFrigates();
Which from what I understand goes against the Law of Demeter. If I'm only supposed to have 'one dot' do I have to have a method in every class to get information from the next? It seems cumbersome.
回答1:
The Law Of Demeter strives to reduce coupling between objects following the principle of information hiding. In your example the method m
which contains the statement:
int numberOfFrigates = model.getSelectedPlanet().getFleet().getNumberOfFrigates();
is interested in the number of Frigates
only. But the chain of method calls do couple the method m
and hence the type T
owning m
to the types returned by getSelectedPlanet()
and getFleet()
.
A solution to avoid this introduced dependencies would be to add a method to your model
which directly returns the number of frigates of the currently selected plane like:
int numberOfFrigates = model.getNumberOfFrigates();
But most often the violation of the principal is an indicator of bad design or misplaced responsibilities. The real solution to this problem most likely is not to expose the information gained by the method chain directly at the consumer like the example shown above, but by moving parts or the whole responsibility of processing closer to the object which holds the required information.
To be as concrete as I can in your example, ask yourself:
Why do I need the number of frigates in my method
m
?May I move parts of processing done in
m
closer to the typesPlanet
orFleet
?
This way you would avoid the method chain as well.
回答2:
What you are doing here is exposing internal state everywhere, in OOP you don't need to get the internal state of an object to get information about it. So it should probably be model.getSelectedPlanetNumberOfFrigates() and in the object you can handle the call to selectedPlanet.getFleetNumberOfFrigates(), ect...
来源:https://stackoverflow.com/questions/43538605/law-of-demeter-in-java