Разве плохо использовать большие внутренние классы в Java? - PullRequest
4 голосов
/ 22 сентября 2010

У меня много объектов типа ContainedClass, хранящихся в объекте типа ContainingClass. Мне нужно получить доступ к объекту контейнера изнутри объектов. На данный момент я делаю это, передавая ссылку на контейнерный объект в конструктор других объектов, таких как ContainedClass cclass = new ContainedClass(this);, и сохраняя его как ContainingClass owner.

Это кажется мне уродливым, и решение, которое мне кажется подходящим, заключается в использовании внутренних классов, но определение для ContainedClass очень большое, и это кажется неуместным. Итак, с какими из вариантов я должен пойти? Или есть еще один очевидный вариант, который мне не хватает?

Вот пример кода, который я нашел в Интернете и показывающий, для чего я буду использовать внутренние классы.

public class TestIt {
  public static void main(String a[]){
     new TestIt().doit();
     /*
      output :
      Hello world!
     */ 
  }
  public void doit() {
      new InnerClass().sayHello();
  }
  public void enclosingClassMethod(){
      System.out.println("Hello world!");
  }


 class InnerClass {
   public void sayHello() {
     TestIt.this.enclosingClassMethod();
   }
 }
}

Я должен добавить, что другим преимуществом внутренних классов, на которые я смотрел, было то, что ContainedClass мог существовать только в ContainerClass, что является желаемым результатом.

Ответы [ 6 ]

3 голосов
/ 22 сентября 2010

То, что вы сделали со своей конструкцией ContainedClass cclass = new ContainedClass(this);, в точности повторяет то, что делают внутренние классы под прикрытием.Могут быть причины не использовать внутренние классы, но размер класса на самом деле не один из них.Я бы использовал реальную языковую функцию, а не подражал ей, если бы не было веской причины не использовать реальную сделку.

2 голосов
/ 22 сентября 2010

Я думаю, это зависит от того, насколько сильно связаны родительские / дочерние классы. Если дочернему элементу нужен доступ ко многим переменным-членам, которые вы бы иначе не открыли через геттеры / сеттеры, или ко многим функциям-членам, которые в противном случае были бы закрытыми, тогда внутреннее расположение классов будет чище.

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

1 голос
/ 22 сентября 2010

Я бы использовал factoryMethod в этом случае:

class ContainingClass {
...
    ContainedClass createContainedObject() {
        return new ContainedClass(this);
    }
...
}

в коде это выглядело бы как

jar = new ContainingClass();
bean = jar.createContainingClass();

Это немного перешагнуло проблему, но я нахожу еевыразительный и позволяет мне выбирать, использовать ли внутренний класс или нет.Лично мне не нравятся большие внутренние классы, мне трудно их читать.

0 голосов
/ 22 сентября 2010
  1. Внутренний класс должен использоваться для создания одноразовых объектов.
  2. если только класс верхнего уровня использует этот класс, то перейдите к внутреннему классу.
  3. Пожалуйста, прочтите Effective Java Джошуа Блоха, чтобы получить ясную идею.
0 голосов
/ 22 сентября 2010

Большие классы любого типа, как правило, должны вызывать недовольство, поскольку они, как правило, имеют множество обязанностей и являются трудной задачей для изоляции и тестирования.

Ваше решение в конечном итоге будет зависеть от того, почему ContainedClass должен знать о ContainerClass,Если целью является совместное использование общего кода данных / кода инициализации между ContainedClasses, то подход Factory может дать хорошие результаты.Или, может быть, если вы просто хотите отслеживать ваши ContainedClasses, тогда вы можете рассмотреть модель Event / EventListener.

0 голосов
/ 22 сентября 2010

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

Родительские / дочерние отношения, которые вы использовали раньше, не так уж редки, и я не считаю их такими уродливыми лично.

...