Сохранение закона Деметры с помощью ArrayLists

Если у меня есть ArrayList объектов, то каждый раз, когда мне нужно вызвать любой метод для члена ArrayList, мне нужно сделать это следующим образом:

list.get(i).doSomething();

Это подозрительно похоже на нарушение Закона Деметры. Я не вижу никакого способа обойти это. Это нормально или я должен переосмыслить, как я делаю такие вещи. Является ли ArrayList объектом, который игнорирует Закон Деметры?


person kabeersvohra    schedule 29.07.2016    source источник
comment
Не могли бы вы объяснить, как вы видите нарушение Закона Деметры?   -  person Matthew    schedule 29.07.2016
comment
Может быть, опишите больше того, что вы хотите сделать? Я не вижу здесь проблемы, это не похоже на то, что вы звоните 10 геттерам подряд.   -  person Tunaki    schedule 29.07.2016
comment
Я понимаю, что это не является серьезным нарушением, но это все равно похоже на запах кода. Это нарушение LoD, потому что я извлекаю объект из ArrayList, а затем вызываю метод для полученного объекта. Технически я должен сделать что-то вроде list.callSomethingOn(i), чтобы сохранить Закон Деметры, но это тоже кажется неправильным.   -  person kabeersvohra    schedule 29.07.2016


Ответы (2)


Это не нарушение.

Если бы у вас был класс

Class A {
    private B b1, b2, b3;

    ...

   private void method() {
       b1.doSomething();
       b2.doSomething();
       b3.doSomething();
   }
}

нарушения нет. Если мы соберем экземпляр B в List<B>, вы получите

Class A {
    private List<B> listOfB;

    ...

   private void method() {
       listOfB.forEach(B::doSomething);
   }
}

Использование List<B> для хранения экземпляров B не приводит к более тесной связи между A и B.

person bradimus    schedule 29.07.2016

Я не вижу здесь нарушения.

Закон Деметры, по идее, предполагает, что сущность знает только о своих соседях, а не о незнакомцах, поэтому, если A что-то нужно от C, она должна поговорить с B, чтобы получить это, и не идти дальше.

Я бы не стал называть List "соседом" применительно к этой концепции. Это объект, управляющий структурой данных, которую вы можете использовать в своей программе. Таким образом, Object, которые содержит ваш список, будут считаться B к вашему A.

Если бы List был реальной сущностью, определенной в вашей программе, вы могли бы быть правы в этом случае. Было бы более разумно, если бы у вашего List был метод, который вызывает ваш Object для выполнения некоторой логики (как вы сказали в комментарии, list.callSomethingOn(i)).

Если этот конкретный экземпляр List является центральным в логике вашей программы, и вы непреклонны в соблюдении закона, вы можете использовать «Декоратор» для List, который добавляет дополнительные методы для работы с содержащимися Object.

person Zircon    schedule 29.07.2016