2016-10-27 5 views
1

Я пытаюсь сделать что-то подобное нижнему псевдокоду. Это противоречит любым правилам или рекомендациям по использованию вложенных классов?Статический вложенный Cass для хранения нескольких списков в внешнем классе

public class Foo{ 
    private list1, list2; 

    Bar bar = new Bar(list1, list2); 
    // use bar.listA, bar.listB, bar.listC, 
    //bar.listD, bar.listE 

    private static class Bar{ 
    private list1, list2; 
    private listA, listB, listC, listD, listE; 

    private Bar(list1, list2) { 
     this.list1 = list1; 
     this.list2 = list2; 
     //logic to split list1 and list2 into 5 lists: listA, listB, listC, listD, listE. 
     //initialize the 5 lists 
    } 
    } 
} 

Я использую вложенный класс по причинам, упомянутых Oracle or the reasons mentioned by Oracle:

  • Это способ логически группировать классы, которые используются только в одном месте
  • Это увеличивает инкапсуляцию
  • Это может привести к более удобному считыванию и код для обслуживания
  • И причины mentioned here

И я вставляю вложенный класс static, потому что мне не нужен прямой доступ к внешним членам класса.

Редактировать: Чтобы быть более конкретным, некоторые вопросы на мой взгляд: Должен ли я использовать ENUM вместо вложенного класса? Должен ли я использовать геттеры/сеттеры для 5 списков в вложенном классе? Является ли конструктор вложенного класса правильным местом для размещения раздельной логики? Можно ли напрямую ссылаться на частные члены вложенного класса во внешнем классе? и т. д.

+0

Трудно рассуждать о таких абстрактных проектах. Какую проблему в мире вы пытаетесь решить? – plalx

+0

, если во внешний экземпляр передано 2 списка, мне просто нужен элегантный способ разделить их на 5 списков и иметь дескриптор для них во внешнем экземпляре (только). Это просто процесс преобразования данных. – Gadam

+0

Если это так, то я бы реализовал функциональное решение во внешнем классе, и я бы не стал беспокоиться о вложенных классах или любой форме OO-дизайна. То есть, если вы не выполните специальные действия в этих списках. Какова логика расщепления, как они будут использоваться? Некоторые виды поведения применимы только к некоторым спискам? – plalx

ответ

1

list1 и list2 содержат «события». И на основе «типа» события, я разделить их на 5 списков

Ну, как общее правило, вы не должны использовать конструктор для их побочных эффектов.

Поэтому я бы выбрал функцию groupEvents в пределах Foo. Если логика группировки значительно сложна, вы можете получить EventGrouper службу без гражданства, которая возвращает экземпляр GroupedEvents или, альтернативно, что-то вроде Map<EventType, List<Event>>.

E.g.

public class Foo { 
    private GroupedEvents groupedEvents; 

    public Foo(List<Event> list1, List<Event> list2) { 
     this.groupedEvents = groupEvents(list1, list2); 
    } 

    private GroupedEvents groupEvents(List<Event> list1, List<Event> list2) { 
     Map<EventType, List<Event>> eventsByType = //perform grouping 
     return new GroupedEvents(eventsByType); 
    } 
} 

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

Теперь я слышу, что вы говорите, хорошо isin't Foo Выполнение группировки в его конструкторе сейчас? Разве мы не ставим проблему выше в цепочке? Ну, хотя верно, что группировка происходит во время построения Foo, клиент объекта Foo не создает экземпляр Foo только для его группировки побочных эффектов (надеюсь, это не так). Группирование просто становится деталью реализации как частью процесса инициализации Foo, и клиент может даже не знать, что такая группировка произошла.

+0

Если я использовал 'GroupedEvents' вместо' Map > ', он просто имел бы 5 частных списков в качестве своих членов, правильно? И могу ли я создать его как вложенный статический класс, так как он будет использоваться только внутри Foo? – Gadam

+0

@Gadam. У него может быть 5 списков, если у вас будет только 5 типов событий, но было бы более гибким, если бы у него просто была функция, такая как 'eventsOfType (тип EventType)' для извлечения событий определенного типа и изнутри храните их на карте. Да, класс может быть вложен, если вы хотите, но он также может быть вложенным, чтобы позволить его тестировать в блоке. – plalx