Закон Деметры на Яве

Я строил RTS, чтобы улучшить свои навыки Java. Я много читал о Законе Деметры, потому что хочу, чтобы мой код был чистым, но я все еще в замешательстве! На данный момент у меня есть такой код, чтобы показать, сколько кораблей определенного типа во флоте на выбранной планете:

int numberOfFrigates = model.getSelectedPlanet().getFleet().getNumberOfFrigates();

Что, насколько я понимаю, противоречит Закону Деметры. Если у меня должна быть только «одна точка», должен ли я иметь метод в каждом классе для получения информации от следующего? Это кажется громоздким.


person Tom F    schedule 21.04.2017    source источник
comment
Вы можете прочитать некоторые мнения здесь   -  person Robin Topper    schedule 21.04.2017


Ответы (2)


Закон Деметры стремится уменьшить связь между объектами, следуя принципу сокрытия информации. В вашем примере метод m, который содержит оператор:

int numberOfFrigates = model.getSelectedPlanet().getFleet().getNumberOfFrigates();

интересует число Frigatesonly. Но цепочка вызовов методов связывает метод m и, следовательно, тип T, владеющий m, с типами, возвращаемыми getSelectedPlanet() и getFleet().

Чтобы избежать этой введенной зависимости, было бы добавить метод к вашему model, который напрямую возвращает количество фрегатов выбранного в данный момент самолета, например:

int numberOfFrigates = model.getNumberOfFrigates();

Но чаще всего нарушение принципа является показателем плохого дизайна или неуместного распределения обязанностей. Реальное решение этой проблемы, скорее всего, заключается не в предоставлении информации, полученной цепочкой методов, непосредственно потребителю, как в примере, показанном выше, а в перемещении частей или всей ответственности за обработку ближе к объекту, который содержит требуемую информацию.

Чтобы быть как можно более конкретным в вашем примере, спросите себя:

Зачем мне количество фрегатов в моем методе m?

Могу ли я переместить части обработки, выполненной в m, ближе к типам Planet или Fleet?

Таким образом, вы также избежите цепочки методов.

person Harmlezz    schedule 21.04.2017
comment
но тогда в модели не будет такого метода, как: int getNumberOfFrigates(){ return selectedPlanet.getFleet().getNumberOfFrigates(); } что также нарушает закон? - person Tom F; 21.04.2017
comment
Я расширил свой ответ, надеясь, что вы найдете правильное решение. Что вы собираетесь делать с numberOfFrigates в m? Помогло ли вам мое расширенное объяснение? - person Harmlezz; 21.04.2017

То, что вы делаете здесь, это раскрытие внутреннего состояния везде, в ООП вам не нужно получать внутреннее состояние объекта, чтобы получить информацию о нем. Так что, вероятно, это должно быть model.getSelectedPlanetNumberOfFrigates(), и в объекте вы можете обработать вызов selectedPlanet.getFleetNumberOfFrigates() и т.д...

person Nyamiou The Galeanthrope    schedule 21.04.2017
comment
Вы имели в виду ООП, когда сказали ПОО? Возможно, это была опечатка, или есть аббревиатура, о которой я не знаю, или это ваш способ сказать, что вам не нравится ООП. :) - person John Pancoast; 02.10.2019
comment
Спасибо, это просто опечатка. - person Nyamiou The Galeanthrope; 02.10.2019
comment
Нп! Я предположил, что это была просто опечатка, но рассмешил свою детскую сторону и просто повеселился. Но, к сожалению, комедийная сторона во мне не так хороша, видимо. :) - person John Pancoast; 02.10.2019