Чи є загальнодоступні поля Java лише трагічним історичним недоліком дизайну? [зачинено]


17

Начебто православ'я Java на даний момент, що в основному ніколи не слід використовувати публічні поля для стану об'єкта. (Я не обов'язково згоден, але це не стосується мого питання.) Враховуючи це, чи було б правильно сказати, що з того місця, де ми сьогодні є, зрозуміло, що публічні поля Java були помилкою / недоліком мовного дизайну? Або є раціональний аргумент, що вони є корисною і важливою частиною мови навіть сьогодні?

Спасибі!

Оновлення: я знаю про більш елегантні підходи, такі як у C #, Python, Groovy тощо. Я не шукаю таких прикладів безпосередньо. Мені справді просто цікаво, чи все ще є хтось глибоко в бункері, бурмочучи про те, наскільки насправді чудові публічні поля, і як всі маси просто вівці тощо.

Оновлення 2: Чітко статичні кінцеві загальнодоступні поля є стандартним способом створення публічних констант. Я мав на увазі більше використання публічних полів для стану об’єкта (навіть непорушного стану). Я думаю, що це здається недоліком дизайну, що слід використовувати загальнодоступні поля для констант, а не для держави ... правила мови повинні виконуватись природним шляхом, синтаксисом, а не настановами.


2
Яка ваша основа, що вони справді є вадою?
Аарон Маківер

1
Чи існує інший спосіб створити символьні постійні вирази на Java зараз?
Едвард Странд

@Aaron Я не заявив, що вони є недоліком, я заявив, що вважаю, що це православ'я в цей момент, що ніколи не слід використовувати громадські поля. Це сприйняття може бути неправильним, але це дійсно те, що я сприйняв.
Аві льон

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

Відповіді:


14

Мені подобаються, якщо поле остаточне і використовується лише внутрішньо в додатку, а не в API для інших програм. Це зробить ваш код коротшим та легшим для читання.

Не слід відкривати публічні поля в API, оскільки, відкриваючи загальнодоступні поля, ви також піддаєте реалізації. Якщо ви getXXX()натомість викриєте це як метод, ви можете змінити реалізацію, не змінюючи інтерфейс API. Наприклад, ви можете змінити та отримати значення з віддаленої служби, але програмам, які використовують API, цього не потрібно знати.

Це життєздатна конструкція для public finalполів у незмінних класах.

З ефективної Java :

Пункт 14: У публічних класах використовуйте методи аксесуара, а не загальнодоступні поля

... якщо клас є пакетно-приватним або є приватним вкладеним класом, немає нічого суттєвого неправильного в розкритті його полів даних. Такий підхід створює менш безладу, ніж підхід методом аксесуара.

Хоча для громадського класу ніколи не є корисним відкриття полів, це менш шкідливо, якщо поля незмінні.

Дивіться також Чому я не повинен використовувати незмінні POJO замість JavaBeans?


Просто цікаво, які ваші причини не виставляти його в API?
Стівен Євріс

2
@Steven: Тому що, відкриваючи загальнодоступні поля, ви також виставляєте реалізацію. Якщо ви getXXX()натомість викриєте це як метод, ви можете змінити реалізацію, не змінюючи інтерфейс API. Наприклад, ви можете змінити та отримати значення з віддаленої служби, але програмам, які використовують API, цього не потрібно знати.
Йонас

@Jonas: Це, як правило, не кандидати на константи.
Стівен Євріс

@Steven: Я говорю не про константи в першу чергу, а про публічні підсумкові поля в непорушних класах. Наприклад, чому я не повинен використовувати незмінні POJO замість JavaBeans?
Йонас

@Jonas: Це теж приємний випадок використання! Можливо, корисно буде трохи оновити свою відповідь, щоб уточнити.
Стівен Євріс

9

Використання пар методу get / set є трагічним недоліком історичного дизайну. Я не можу придумати іншу мову, яка реалізує властивості як багатослівно, так і неефективно.


1
Незважаючи на те, що це правда, це дещо дотично до питання, який (по суті) обумовлює вибір між методами встановлення / отримання та публічними полями, чи є вагомі причини віддати перевагу полям у якійсь ситуації? Те, що інші мови пропонують кращі рішення проблеми, мені здається, не має значення.
Жуль

5

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


2
java.awt.Pointа друзі - трохи кошмар.
Том Хотін - тайклін

@ TomHawtin-tackline: Проблема Pointполягає в тому, що неоднозначно, чи повинна змінна типу Pointінкапсулювати місця розташування, чи передбачає інкапсуляцію ідентичності організації з розташуванням, яке може змінюватися. Концептуально я вважаю, що код, який проходить навколо, Pointдуже схожий на код, який проходить навколо масивів.
supercat

Отже, якщо я отримаю Pointта модифікую його, я повинен очікувати, що об'єкт, на який він посилається, чисто оновити на екрані? Ні, проблема Pointполягає в тому, що він є змінним. Ми мали String/ StringBufferале ідея, здавалося, не пробилася. / Проходження масивів навколо має подібні проблеми.
Том Хотін - тайклін

5

Для визначення публічних констант все ще корисно. Напр

загальнодоступний статичний кінцевий int DAYS_IN_WEEK = 7;

Однак все-таки віддайте перевагу перелікам, де це можливо. Напр

public enum Day {
    SUNDAY, MONDAY, TUESDAY, WEDNESDAY, 
    THURSDAY, FRIDAY, SATURDAY 
}

Для моделювання простих структурних класів також корисно. Немає підстав створювати геттер і сетер для кожного поля, коли вони все одно є загальнодоступними.

class Point
{
    public int x, y;
    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

Але знову ж таки, багато хто буде стверджувати, що структури не мають місця в такій мові, як Java ...

1
@delnan: Вони майже такі ж, як і JavaBeans, але JavaBeans набагато більш багатослівний і не безпечний. Див. Чому я не повинен використовувати незмінні POJO замість JavaBeans?
Йонас

Деякі конкретні спостереження щодо Android: Енуми оцінюються повільніше, ніж ints, і цього слід уникати. Також поля, до яких часто звертаються сетери та геттери в тісних петлях, також можуть отримати користь від публічного доступу.
Nailer

2

До того, як IDE набули широкого поширення, оприлюднення всіх ваших полів було потужним інструментом для швидкого створення прототипів / доказів концепцій.

На сьогоднішній день існує дуже мало приправ для їх використання, коли ви можете генерувати пари геттера / сеттера одним клацанням миші.


4
Але 10 public finalполів читабельніше, ніж 10 getXXX()методів.
Йонас

1
@ Jonas Так, але ми не говоримо про остаточні поля тут. Якщо ваші загальнодоступні кінцеві поля також є статичними, вони є константами, і constключового слова буде досить, якщо вони не є статичними, вони є серйозним порушенням інкапсуляції.
biziclop

3
@biziclop згідно Вікіпедії : "хоча зарезервоване як ключове слово на Java, const не використовується і не має функції"
Avi Flax

@Avi Flax Так, але це можна було використати для позначення констант, тим самим усуваючи необхідність оголошувати константи загальнодоступними полями.
biziclop

2
Якщо припустити, що геттер / пара сетерів взагалі підходить, тобто. Часто це не так.
Девід Торнлі

2

Це суб'єктивно, але моя думка полягає в тому, що все суспільне / приватне поняття застаріле і назад.

У python немає публічного / приватного; все в основному публічно. Це не викликало багатьох проблем.

У Java ви схильні створювати безглузді геттери / сетери для кожного поля, щоб уникнути гріха відзначати їх "загальнодоступними". (ІМХО, якщо ви виявите, що ви робите це, вам слід просто позначити їх публічно).


Python дозволяє позначати речі як приватні, префіксуючи імена __. Це не на 100% приватне, оскільки все ще є способи отримати доступ до цих змінних і методів, але тоді в C # ви можете робити подібні речі з відображенням.
Адам Лір
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.