Этот метод вызова нарушает закон Деметры? - PullRequest
1 голос
/ 24 ноября 2011

Скажем, у вас есть что-то вроде следующего (к сожалению, мне не разрешено публиковать оригинальный код):

public void foo() {
    MyObject obj = getMyObject();

    bar(obj);
}

public void bar(MyObject obj) {
   Type type = new Type(obj.getOtherObject());
}

foo, звонки bar, передача obj.Но вместо использования obj он вызывает геттер для получения необходимой информации.Это нарушает Закон Деметры?

Было бы лучше написать что-то вроде этого:

public void foo() {
    MyObject obj = getMyObject();

    bar(obj.getOtherObject());
}

public void bar(MyOtherObject otherObj) {
   Type type = new Type(otherObj);
}

1 Ответ

2 голосов
/ 24 ноября 2011

Действительно, согласно вики о Законе Деметры :

Фундаментальное понятие состоит в том, что данный объект должен принимать как минимум насколько возможно о структуре или свойствах чего-либо еще ...

Ваш bar предполагает, что данный MyObject (конкретный тип, который так сильно связан, опять же с LoD) имеет метод с именем getOtherObject, поэтому предлагаемое вами решение сортирует предположение и приближает код к соблюдению LoD , Вы можете пойти еще дальше и вместо этого указать тип, который bar хочет:

bar(new Type(obj.getOtherObject());

В зависимости от вашего языка, вы не можете передать интерфейс / контракт вместо сплошного типа? Это превратит сильную связь в более слабую.

Конечно, если это все внутреннее для данного объекта, то, возможно, это не нарушает LoD, потому что это «близкий друг»:

  • Каждый юнит должен иметь ограниченные знания о других юнитах: только юниты, «тесно связанные» с текущим юнитом.
  • Каждый юнит должен разговаривать только со своими друзьями; не разговаривай с незнакомцами.
  • Поговорите только со своими ближайшими друзьями.

В ОО, я думаю, ваш исходный код нарушает LoD на основании этого аргумента:

... объект A может запросить услугу (вызвать метод) объекта экземпляр B, но объект A пока не может «достучаться» до объекта B, чтобы получить к нему доступ другой объект, C, чтобы запросить его услуги. Это будет означать, что объект А неявно требует большего знания внутреннего объекта структура.

Мне кажется, что вы используете obj для вызова getOtherObj. Ваш предложенный код является потенциальным решением.

...