Java / Android: анонимные локальные классы против именованных классов

Я хотел бы спросить, какова хорошая практика использования анонимных классов по сравнению с именованными внутренними классами?

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

someButton.setOnClickListener(
    new View.OnClickListener() {
        public void onClick(View v) {
            // do something...
        }
    }
);

Каждый из таких анонимных классов имеет размер 5-20 строк - достаточно маленький и хорошо подходит для рекомендаций из Java ™ в книге Nutshell :

В общем, вы должны рассмотреть возможность использования анонимного класса вместо локального класса, если:

  • У класса очень короткое тело.
  • Требуется только один экземпляр класса.
  • Класс используется сразу после его определения.
  • Имя class не делает ваш код более простым для понимания.

Но проблема, IMO, в том, что onCreate становится довольно большим, и код становится более сложным для чтения и понимания, если быстро взглянуть на него. Это все еще легко понять, но просто слишком велико.

Так что было бы лучше практиковать в таком случае - иметь кучу маленьких внутренних подклассов, где каждый из них красиво отделен, но использовать только один раз или лучше продолжать использовать анонимные классы вместо этого?

8
задан Laimoncijus 26 August 2010 в 16:05
поделиться

6 ответов

Я не думаю, что есть четкий ответ так или иначе. Оба стиля работают нормально, это действительно то, что вы предпочитаете.

Еще один вариант — получить

содержимое каждого onClick с помощью одного вызова функции, что сделает анонимные классы очень короткими. То есть:

someButton.setOnClickListener(
    new View.OnClickListener() {
        public void onClick(View v) {
            doSomeButtonClick();
        }
    }
);


private void doSomeButtonClick() {
  // do something
}
8
ответ дан 5 December 2019 в 10:00
поделиться

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

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

1
ответ дан 5 December 2019 в 10:00
поделиться

Рефакторинг onCreate() в отдельные методы, сгруппированные по общей функциональности, чтобы у вас были логические единицы. Если графический интерфейс сложный, он поможет вам позже.

РЕДАКТИРОВАТЬ:

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

5
ответ дан 5 December 2019 в 10:00
поделиться

Как следует из цитаты, это нечто субъективное. Вам нужно выяснить, что считается «очень коротким» и «более простым для понимания» для себя, чтобы определить, в какой момент размер кода пересекает линию от чего-то, что имеет смысл как анонимный класс, к чему-то, что имеет смысл быть его собственным Блок.

Любые ответы, которые кто-либо может дать вам по этому поводу, основаны на их собственных субъективных оценках того, что такое «короткий» и сколько строк кода требуется, чтобы перестать быть «коротким».

0
ответ дан 5 December 2019 в 10:00
поделиться

Я делаю приложения для рабочего стола/Swing, но я думаю, что концепции те же.

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

Это дает мне несколько преимуществ:

  • Весь код обработки событий находится в одном классе.
  • Любое пересечение функций между событиями легко обнаруживается и обрабатывается.
  • Любое затронутое состояние может храниться и контролироваться в одном классе.
  • Весь код обработки событий отделен от кода макета компонента.
  • Слой представления (панель) ничего не знает о слое контроллера.

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

3
ответ дан 5 December 2019 в 10:00
поделиться

Помещение этих элементов в именованные классы дает несколько преимуществ.

Первый вариант, о котором вы упомянули, сделает метод onCreate() более лаконичным и понятным.

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

Третье — более простое разделение обязанностей. Если вы решите перейти на модель IoC, вам будет намного проще внедрить именованные реализации слушателей.

0
ответ дан 5 December 2019 в 10:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: