2015-11-19 3 views
15

Существует много вопросов и ответов об использовании публичных полей в объектно-ориентированном программировании, и большинство из них рекомендует не использовать общедоступные поля по многим причинам.Почему у некоторых андроидов есть открытые поля?

Но когда я посмотрел код Android, я обнаружил, что некоторые классы используют общедоступные поля. Например, Android.view.View имеет общедоступные поля mCachingFailed и mAttributes.

Почему они общедоступны? Трудно думать, что это ошибка в Google и AOSP.

+0

Почему вы спрашиваете нас? Спросите авторов. Они знают. – EJP

+2

@EJP Они сказали, что сделали это намеренно в Android-трекер (они использовали public + '@ hide', а не частные) У меня нет личного контакта с разработчиками Android, и я думаю, что трекер для Android не для вопросов и ответов. –

+0

Скорее всего, по соображениям производительности, то есть классы из других пакетов должны обращаться к ним по некоторому критическому пути. Действительно, 'android.widget.ListView' ссылается на него в' drawChild (Canvas canvas, View child, long drawingTime) '. Но без каких-либо комментариев от авторитетных фигур это просто гипотеза. – Kai

ответ

13

Это не является по своей сути ошибкой иметь публичные поля. Это не означает, что, как отмечается в примечании к награде, «ООП-фундаментальное нарушение». После того, как все эти два класса (в большинстве случаев) идентичны:

public class DemoA { 
    public int field; 
} 

public class DemoB { 
    private int field; 

    public int getField() { return field; } 
    public void setField(int value) { field = value; } 
} 

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

Преимущества геттеров и сеттеров, даже если они не выполняют никакой другой работы, кроме чтения и записи в поля, заключается в том, что они абстрагируют тот факт, что данные хранятся в поле вообще. Он может храниться во внешнем источнике данных или вычисляться «на лету» или независимо от того, что вам нужно, и вызывающим абонентам не нужно беспокоиться о том, как осуществляется поведение. Это, безусловно, хорошая практика вообще, потому что она отделяет проблемы вызывающих абонентов (API) от ваших проблем (реализации).

Однако иногда это просто излишний, и вполне разумно публиковать открытые поля, если это лучший способ обеспечить поведение, которое вам нужно. Чаще всего это делается для value types, классов, которые существуют only, чтобы сгруппировать несколько полей вместе. Там мало пользы для написания десятков геттеров и сеттеров, когда все, что вам нужно, чтобы сделать класс, можно сделать, просто сделав поля общедоступными.

Как практический вопрос, Android имеет дополнительную заботу. Вызов метода дорог и количество методов, которые приложение может (легко) определить, равно limited to ~65k. В тех случаях, когда это безопасно, разоблачение поля напрямую снижает накладные расходы метода на два и экономит ценное процессорное время. Это может показаться не очень много, но оно быстро складывается.

+0

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

+0

Конечно, это потенциально незначительно быстрее. Но как компилятор, так и JIT могут потенциально оптимизировать геттеры/сеттеры для фактического доступа к полям, поэтому, вероятно, это очень ограниченные накладные расходы. Более того, вы должны избегать принятия конструктивных решений по причинам эффективности, пока не убедитесь, что это узкое место. Стоимость написания плохого кода во имя эффективности намного выше, чем стоимость небольшой неэффективности, с которой иногда сталкиваются хорошие модели. – dimo414

+0

@mad_manny Я думаю, что это то, что вы читаете: http://developer.android.com/training/articles/perf-tips.html#GettersSetters «Разумно следовать общепринятым объектно-ориентированным практикам программирования и иметь геттеры и сеттеры в открытый интерфейс, но внутри класса вы всегда должны напрямую обращаться к полям ». –

6

Заканчивать этот раздел из developer.android.com:

на родных языках, как C++, это обычная практика для использования добытчиков (я = GetCount()) вместо того, чтобы получить доступ к области непосредственно (я = mCount). Этот является отличной привычкой для C++ и часто практикуется в других объектах ориентированных языках, таких как C# и Java, потому что компилятор обычно может использовать , а если вам нужно ограничить или отлаживать доступ к полю , вы можете добавить код в в любой момент.

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

Без JIT, прямой доступ к полю примерно в 3 раза быстрее, чем использование трициального приемника . С JIT (где прямой доступ к полю дешевле, чем , доступ к локальному), прямой доступ к полю примерно в 7 раз быстрее, чем , вызывающий тривиальный приемник.

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

http://developer.android.com/training/articles/perf-tips.html#GettersSetters

Скорее всего, это причина, вы видите общественности поля в AOSP.

+0

Здорово знать, что это было упомянуто на официальном веб-сайте разработчика Android. Тем не менее, мы должны отметить, что веб-страница посвящена предотвращению «внутренних» getters/seters и не упоминает ничего о правильности доступа к публичному полю непосредственно извне класса. (См. Также: http://stackoverflow.com/questions/6716442/android-performance-avoid-internal-getters-setters) – Taka

Смежные вопросы