Подтвердить что ты не робот

Почему странное соглашение об именах "AlertDialog.Builder" вместо "AlertDialogBuilder" в Android

Почему бы не

AlertDialogBuilder builder = new  AlertDialogBuilder(this);
builder.setTitle("foo");

вместо

AlertDialog.Builder builder = new  AlertDialog.Builder(this);
builder.setTitle("foo");

Обновление: я хочу знать причину такого рода написания/организации

4b9b3361

Ответ 1

Builder - это статический внутренний класс внутри класса AlertDialog. Чтобы создать объект класса Builder, вам нужно вызвать AlertDialog.Builder.

Как нет класса, такого как AlertDialogBuilder, поэтому вы не можете этого сделать.

Если вы хотите, вы также можете использовать как показано ниже.

Builder builder = new Builder(this);
builder.setTitle("foo");

Но для этого вам нужно импортировать класс Builder в класс, например

import android.app.AlertDialog.Builder;

вместо

import android.app.AlertDialog;

Простой пример

class A{
     static class B{}
}

вы не можете использовать

AB obj = new AB();

вы должны использовать

A.B obj = new A.B();

Надеюсь, теперь вы поняли.

Ответ 2

В соответствии с Javadocs вложенные классы (и в этом случае статические вложенные классы) обычно используются для трех вещей:

  • Логически группирующие классы, которые будут использоваться только вместе.
  • Увеличение инкапсуляции.
  • Повышение удобочитаемости и ремонтопригодности кода.

Точка №3 - одна из причин, по которой многие разработчики используют статические вложенные классы. Возьмем, к примеру, ViewHolder pattern в Android-разработке. В ListAdapter мы можем упростить кэширование списков путем управления содержимым каждого элемента списка в ViewHolder (или аналогично названном внутреннем классе). В этой ситуации легко заметить, что этот конкретный ViewHolder предназначен только для этого класса, и когда мы меняем его, мы не меняем ни одного. Это означает, что нам не нужны List1ViewHolder, List2ViewHolder,..., ListNViewHolder. Каждый элемент List -type может иметь свой собственный ViewHolder.

Точка №2 немного менее актуальна для этой точки, потому что мы имеем дело со статическими внутренними классами (это то, что Builder). Но в этом случае он предотвращает доступ к внешним классам класса внутреннего класса.

Точка № 1 здесь большая, поэтому я сохранил ее для последней. Подумайте о ситуациях, в которых вы будете использовать AlertDialog.Builder. Я могу гарантировать с 100% уверенностью, что каждый раз, когда вы используете AlertDialog.Builder, он будет находиться в здании/создании/обработке AlertDialog. Следовательно, это означает, что любое использование AlertDialog.Builder связано с тем, как работает AlertDialog. (Это несколько связано с точкой № 3, проще поддерживать два класса в одном файле, чем разделять их.)

Подобно точкам № 1 и № 3, но также и его собственный обряд, заключается в том, что, сохраняя Builder внутри AlertDialog, мы не загрязняем пространство имен пакетов android.app. Мы все еще сохраняем только AlertDialog внутри него; но Builder скрывается внутри этого.

Android - это не единственная система, которая делает это; MotiveWave SDK делает это также, как и Adobe Access и eBay SDK (для которых мне не хватает ссылок). Я также считаю, что Java EE также использует эту методологию. Вы также часто видите его в типах Enum, что, в свою очередь, связано с причинами, указанными в пункте №.

Теперь вы спросили, почему мы используем AlertDialog.Builder вместо new AlertDialog() и создаем его из объекта, а не из строителя. Ответ здесь такой же, как factory шаблон метода, который обычно наблюдается на Java и других объектно-ориентированных языках программирования. Примечательно (из Википедии), есть три причины для этого:

  • Создание объекта исключает его повторное использование без значительного дублирования кода.
  • Для создания объекта требуется доступ к информации или ресурсам, которые не должны содержаться в классе компоновки.
  • Управление создаваемыми объектами жизненного цикла должно быть централизовано для обеспечения согласованного поведения в приложении.

Они объясняют себя довольно хорошо; они говорят против дублирования кода (способного обрабатывать все функциональные возможности создания в пределах одного класса), несанкционированного доступа (плохие методы инкапсуляции) и последовательного поведения конструкции. Также здесь не указано читаемость кода.

Я подозреваю - по догадке - что AlertDialog - очень ресурсоемкий процесс. Он останавливает части ОС, удерживает других, загружает системные ресурсы и т.д. Поскольку этот ответ подробно, мы не хотим предоставлять прямой доступ к внешнему классу (AlertDialog в этом случае). Это позволяет Builder корректно обрабатывать все ресурсоемкие операции. Это также мешает нам справляться с эзотерическими ситуациями, которые разработчики ОС рассматривали, но мы этого не сделали.

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

Ответ 3

Я попытаюсь очистить вас от этой организации.

Прежде всего, Builder - это класс внутри класса AlertDialog. Зачем вам создавать класс внутри другого класса? Я лично создаю только вложенные классы, если хочу добавить больше функциональности к существующему классу и не верю, что с точки зрения проектирования, что класс должен быть расширен. Я уверен, что можно было бы спорить об этом, так как есть много разных способов добавить больше функциональности в класс; но вложенные классы могут быть предпочтительнее других (для некоторых людей).

Здесь оракулы точки зрения на вложенные классы.

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

В этом случае я считаю, что ребята в Google обнаружили, что вместо создания нового класса, называемого AlertDialogBuilder, по сравнению с AlertDialog.Builder, это потому, что оба дают одинаковые результаты; диалоговое окно, отображающее некоторую информацию на экране с помощью некоторых кнопок. Единственное различие между обоими (я думаю) заключается в том, что вы можете установить положительную, нейтральную и отрицательную кнопку на AlertDialog.Builder(что дает больше функциональности классу, но не обязательно больше, что класс должен быть расширен, снова личное мнение).

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

Надеюсь, это поможет.

Ответ 4

Подход, используемый для построения AlertDialog Object, называется шаблоном Builder для повышения удобочитаемости. Когда вы хотите построить новый объект, но для этого объекта требуется много свойств, чтобы создать его, как слишком много параметров (более 4), переходящих к конструктору, вы смутитесь. Если вы хотите узнать больше о шаблоне построителя, я думаю, что этот ответ будет отвечать вашим потребностям. Конструкция AlertDialog очень похожа на пример в ссылке:

@Override 
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new AlertDialog.Builder(getActivity())
           .setMessage("Do you really want to exit?")
           .setCancelable(false)
           .setNegativeButton("No", 
                    new DaialogInterface.onClickListener() {
                            public void onClick(DialogInterface dialog, 
                            int id) {
                                    ((AlertDialogActivity) getActivity())
                                                .continueShutdown(false);
                                }

                        })
           .setPositibeButton("Yes", 
                    new DialogInterface.onClickListener()) {
                        public void onClick(
                                final DialogInterface dialog, int id) {
                                    ((AlertDialogActivity) getActivity())
                                                .continueShutdown(true);
                                }
                    }).onCreate();
}

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

AlertDialog ad = new AlertDialog(getActivity(), "Do you really want to exit?", 
                                 false, "No", .... )//and the list goes on 

Сравните этот подход с методом onCreateDialog Я думаю, что метод onCreateDialog выигрывает правильно?