Какое правило при раскрытии методов инкапсулированного класса - PullRequest
5 голосов
/ 29 мая 2010

Рассмотрим следующую аналогию: Если у нас есть класс «Car», мы можем ожидать, что в нем будет экземпляр «Engine». Как в: «У машины HAS-A двигатель». Аналогично, в классе «Engine» мы ожидаем экземпляр «Starting System» или «Cooling System», каждый из которых имеет свои соответствующие подкомпоненты.

По характеру инкапсуляции разве не правда, что у автомобиля "HAS-A" в нем "шланг радиатора", а также у двигателя?

Следовательно, уместно ли ОО делать что-то вроде этого:

public class Car {
   private Engine _engine;

   public Engine getEngine() {
      return _engine;
   }

   // is it ok to use 'convenience' methods of inner classes?
   // are the following 2 methods "wrong" from an OO point of view?
   public RadiatorHose getRadiatorHose() {
      return getCoolingSystem().getRadiatorHose();
   }

   public CoolingSystem getCoolingSystem() {
       return _engine.getCoolingSystem();
   }
}

public class Engine {
    private CoolingSystem _coolingSystem;

    public CoolingSystem getCoolingSystem() {
        return _coolingSystem;
    }
}

public class CoolingSystem {
    private RadiatorHose _radiatorHose;

    public RadiatorHose getRadiatorHose() {
        return _radiatorHose;
    }
}

public class RadiatorHose {//...
}

Ответы [ 4 ]

4 голосов
/ 29 мая 2010

Вот действительно хорошая (и довольно короткая) статья о законе деметры, которая называется «Бумажник», «Бумажник» и «Закон Деметры»:

http://www.ccs.neu.edu/research/demeter/demeter-method/LawOfDemeter/paper-boy/demeter.pdf

Когда вы прочитали это, вы должны прочитать эту короткую статью, в которой подробно рассказывается, сколько людей неправильно истолковывают закон Деметры. Таким образом, статья служит действительно хорошим объяснением. Это точно называется «Закон Деметры - не упражнение по подсчету точек» !!!!

http://haacked.com/archive/2009/07/14/law-of-demeter-dot-counting.aspx

4 голосов
/ 29 мая 2010

Проверьте по Закону Деметры .

2 голосов
/ 29 мая 2010

Достигая внутри других инкапсулированных классов, вы напрашиваетесь на неприятности. Весь смысл инкапсуляции в том, что вам не нужно знать, как реализована функция, а именно, что она делает и как получить к ней доступ.
Если бы я изменил каким-либо образом систему охлаждения и шланг радиатора, двигатель не должен быть затронут вообще. В случае, если вы выдвигаете, хотя это может вызвать проблемы. Это действительно не правильный ООП, и в будущем возникнут проблемы.

0 голосов
/ 29 мая 2010

Как правило, вы можете сначала использовать язык природы для описания отношений между компонентами, которые в последнее время представлены в виде классов, а затем использовать определенные диаграммы для представления этих отношений. Если на ваших диаграммах соединены два компонента, они должны иметь определенное соединение в вашей программе. В вашем случае вы можете определить, является ли «двигатель» экземпляром «автомобиля», а «система охлаждения» является экземпляром «двигателя», наблюдая, есть ли связи между этими компонентами на диаграмме. (Этот процесс фактически является интуицией языка моделирования ОО, такого как UML.)

На самом деле, я не вижу ничего плохого в вашем коде. Я не автомобильный человек, поэтому я могу ошибаться в понимании системы. Но если двигатель реального автомобиля нуждается в системе охлаждения, я думаю, что вы делаете правильно. Да, класс «engine» действительно вызывает свойство класса «система охлаждения», но поскольку «engine» использует открытый метод для вызова «системы охлаждения», это правильный путь. Опять же, я не знаю реальную автомобильную систему, поэтому я могу ошибаться в этом конкретном дизайне.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...