Czy publiczne pola Javy są w tym momencie tragiczną wadą historycznego projektu? [Zamknięte]

17

Wydaje się, że w tym momencie ortodoksja Java nie powinna zasadniczo używać pól publicznych do określania stanu obiektu. (Niekoniecznie się zgadzam, ale to nie dotyczy mojego pytania.) Biorąc to pod uwagę, czy byłoby słuszne powiedzieć, że z miejsca, w którym jesteśmy dzisiaj, jasne jest, że publiczne pola Javy były błędem / wadą projektu językowego? A może istnieje racjonalny argument, że są one użyteczną i ważną częścią języka, nawet dzisiaj?

Dzięki!

Aktualizacja: Wiem o bardziej eleganckich podejściach, takich jak C #, Python, Groovy itp. Nie szukam bezpośrednio tych przykładów. Zastanawiam się tylko, czy w bunkrze jest jeszcze ktoś, mamrocząc o tym, jak wspaniałe są naprawdę publiczne pola i jak masy są tylko owcami itp.

Aktualizacja 2: Wyraźnie statyczne końcowe pola publiczne są standardowym sposobem tworzenia stałych publicznych. Odniosłem się bardziej do używania pól publicznych dla stanu obiektu (nawet stanu niezmiennego). Myślę, że wydaje się to błędem projektowym, w którym należy używać pól publicznych dla stałych, ale nie dla stanu… reguły języka powinny być egzekwowane naturalnie, przez składnię, a nie przez wytyczne.

Avi Len
źródło
2
Jaka jest twoja podstawa, że ​​rzeczywiście są one wadą?
Aaron McIver
1
Czy istnieje teraz inny sposób tworzenia stałych symbolicznych wyrażeń w Javie?
Edward Strange
@Aaron Nie twierdziłem, że są wadą, stwierdziłem, że w tym momencie postrzegałem to jako ortodoksję, że nigdy nie należy używać pól publicznych. To spostrzeżenie może być błędne, ale tak właśnie postrzegałem.
Avi Flax
@Crazy Eddie Zapomniałem o tym zastosowaniu, myślałem raczej o bardziej powszechnym użyciu pól, stan. Zmienię pytanie.
Avi Flax

Odpowiedzi:

14

Lubię je, o ile pole jest ostateczne i jest używane tylko wewnętrznie w aplikacji, a nie ujawniane w interfejsie API dla innych aplikacji. Dzięki temu kod jest krótszy i bardziej czytelny.

Nie należy ujawniać pól publicznych w interfejsie API, ponieważ ujawniając pola publiczne, narażasz także implementację. Jeśli getXXX()zamiast tego udostępnisz go jako metodę, możesz zmienić implementację bez zmiany interfejsu API. Na przykład możesz zmienić i uzyskać wartość ze zdalnej usługi, ale aplikacje korzystające z interfejsu API nie muszą o tym wiedzieć.

Jest to realny projekt dla public finalpól w niezmiennych klasach.

Z Effective Java :

Punkt 14: W klasach publicznych używaj metod akcesorów, a nie pól publicznych

... jeśli klasa jest prywatna dla pakietu lub jest prywatną klasą zagnieżdżoną, nie ma nic złego w ujawnianiu jej pól danych. Takie podejście generuje mniej bałaganu niż podejście oparte na metodzie akcesorium.

Chociaż nigdy nie jest dobrym pomysłem, aby klasa publiczna wystawiała pola bezpośrednio, jest mniej szkodliwe, jeśli pola są niezmienne.

Zobacz także Dlaczego nie powinienem używać niezmiennych POJO zamiast JavaBeans?

Jonas
źródło
Zastanawiam się tylko, jakie są powody, dla których nie ujawniasz go w interfejsie API?
Steven Jeuris
2
@Steven: Ponieważ ujawniając pola publiczne, ujawniasz również implementację. Jeśli getXXX()zamiast tego udostępnisz go jako metodę, możesz zmienić implementację bez zmiany interfejsu API. Na przykład możesz zmienić i uzyskać wartość ze zdalnej usługi, ale aplikacje korzystające z interfejsu API nie muszą o tym wiedzieć.
Jonas
@Jonas: Na ogół nie są to kandydaci na stałe.
Steven Jeuris
@Steven: Nie mówię przede wszystkim o stałych, ale publicznych końcowych polach w niezmiennych klasach. Np. Zobacz Dlaczego nie powinienem używać niezmiennych POJO zamiast JavaBeans?
Jonas
@Jonas: To także fajny przypadek użycia! Być może warto nieco zaktualizować swoją odpowiedź, aby ją wyjaśnić.
Steven Jeuris
9

Zastosowanie par metod get / set jest tragiczną wadą historycznego projektu. Nie mogę wymyślić innego języka, który implementuje właściwości jako mówiony i nieefektywny.

Kevin Cline
źródło
1
Chociaż jest to prawda, jest to nieco styczne do sedna pytania, które (zasadniczo) biorąc pod uwagę wybór między metodami set / get a polami publicznymi, czy istnieją jakieś uzasadnione powody, aby preferować pola w jakiejś sytuacji? Wydaje mi się, że inne języki oferują lepsze rozwiązania tego problemu.
Jules
5

Myślę, że publiczne pola są odpowiednie dla klasy, która jest zasadniczo typem wartości, takim jak liczba zespolona lub punkt, w którym klasa robi niewiele więcej niż grupowanie pierwotnych typów razem, takich jak struktura typu C i może definiować kilka operatorów.

Karl Bielefeldt
źródło
2
java.awt.Pointa przyjaciele są trochę koszmarem.
Tom Hawtin - tackline
@ TomHawtin-tackline: Problem Pointpolega na tym, że nie jest jednoznaczne, czy zmienna typu Pointma obudowywać lokalizacje, czy też ma zawierać w sobie tożsamość bytu z lokalizacją, która może się zmienić. Pod względem koncepcyjnym uważałbym, że kod, który przechodzi, Pointjest bardzo podobny do kodu, który przechodzi wokół tablic.
supercat
Więc jeśli dostanę Pointi zmodyfikuję go, powinienem oczekiwać, że obiekt, którego dotyczy, czyści aktualizację na ekranie? Nie, problem Pointpolega na tym, że można go modyfikować. Mieliśmy String/ StringBufferale pomysł nie doszedł do skutku. / Przekazywanie tablic ma podobne problemy.
Tom Hawtin - tackline
5

Nadal przydatne jest definiowanie stałych publicznych. Na przykład

public static final int DAYS_IN_WEEK = 7;

Jednak nadal wolą enum tam , gdzie to możliwe. Na przykład

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

Przydaje się także do symulacji prostych klas struktur . Nie ma powodu, aby tworzyć getter i setter dla każdego pola, gdy i tak są one publiczne.

class Point
{
    public int x, y;
    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}
Steven Jeuris
źródło
Ale z drugiej strony wielu twierdzi, że struktury nie mają miejsca w języku takim jak Java ...
1
@delnan: Są prawie takie same jak JavaBeans, ale JavaBeans jest znacznie bardziej gadatliwy i nie jest bezpieczny dla wątków. Zobacz, dlaczego nie powinienem używać niezmiennych POJO zamiast JavaBeans?
Jonas
Niektóre spostrzeżenia dotyczące Androida: Wyliczenia są wolniejsze do oszacowania niż ints i należy ich unikać. Również pola często używane przez osoby ustawiające i pobierające w ciasnych pętlach również mogą korzystać z upublicznienia.
Nailer
2

Zanim IDE stały się powszechne, upublicznienie wszystkich pól było potężnym narzędziem do szybkiego tworzenia prototypów / proofów koncepcji.

W dzisiejszych czasach jest bardzo niewiele wymówek, aby z nich korzystać, kiedy można wygenerować parę getter / setter za pomocą kliknięcia myszy.

biziclop
źródło
4
Ale 10 public finalpól jest bardziej czytelnych niż 10 getXXX()metod.
Jonas
1
@Jonas Tak, ale nie mówimy tutaj o końcowych polach. Jeśli publiczne pola końcowe są również statyczne, są stałe, a constsłowo kluczowe wystarczyłoby, jeśli nie są statyczne, stanowią poważne naruszenie hermetyzacji.
biziclop
3
@biziclop według Wikipedii : „chociaż jest zastrzeżone jako słowo kluczowe w Javie, const nie jest używane i nie ma żadnej funkcji”
Avi Flax
@Avi Flax Tak, ale można go było wykorzystać do oznaczania stałych, eliminując w ten sposób potrzebę deklarowania stałych jako pól publicznych.
biziclop
2
Zakładając, że para pobierająca / ustawiająca jest w ogóle odpowiednia, to znaczy. Często tak nie jest.
David Thornley,
2

Jest to subiektywne, ale moim zdaniem całe pojęcie publiczne / prywatne jest przestarzałe i zacofane.

W Pythonie nie ma publicznych / prywatnych; zasadniczo wszystko jest publiczne. Nie spowodował wielu problemów.

W Javie tworzysz bezcelowe programy pobierające / ustawiające dla każdego pola, aby uniknąć grzechu oznaczania ich jako „publicznych”. (IMHO, jeśli to robisz, powinieneś po prostu oznaczyć je jako publiczne).

hasen
źródło
Python pozwala ci oznaczać rzeczy jako prywatne, poprzedzając je nazwami __. Nie jest w 100% prywatny, ponieważ wciąż istnieją sposoby na dostęp do tych zmiennych i metod, ale w języku C # możesz robić podobne rzeczy za pomocą refleksji.
Adam Lear