I campi pubblici di Java sono solo un tragico difetto di progettazione storica a questo punto? [chiuso]


17

Sembra essere l'ortodossia Java a questo punto che non si dovrebbe praticamente mai usare i campi pubblici per lo stato degli oggetti. (Non sono necessariamente d'accordo, ma non è rilevante per la mia domanda.) Detto questo, sarebbe giusto dire che da dove siamo oggi, è chiaro che i campi pubblici di Java erano un errore / difetto del design del linguaggio? O c'è un'argomentazione razionale secondo cui sono una parte utile e importante della lingua, anche oggi?

Grazie!

Aggiornamento: conosco gli approcci più eleganti, come in C #, Python, Groovy, ecc. Non sto cercando direttamente quegli esempi. Mi sto davvero chiedendo se c'è ancora qualcuno nel profondo di un bunker, che borbotta su quanto siano davvero meravigliosi i campi pubblici e come le masse siano tutte solo pecore, ecc.

Aggiornamento 2: i campi pubblici finali chiaramente statici sono il modo standard per creare costanti pubbliche. Mi riferivo maggiormente all'utilizzo di campi pubblici per lo stato dell'oggetto (anche lo stato immutabile). Sto pensando che sembra un difetto di progettazione che uno dovrebbe usare i campi pubblici per le costanti, ma non per lo stato ... le regole di una lingua dovrebbero essere applicate naturalmente, dalla sintassi, non dalle linee guida.


2
Qual è la tua base che sono davvero un difetto?
Aaron McIver,

1
Esiste un modo diverso di creare espressioni simboliche costanti in Java adesso?
Edward Strange,

@Aaron Non stavo affermando che sono un difetto, stavo affermando che l'ho percepito come un'ortodossia a questo punto che non si dovrebbe mai usare i campi pubblici. Quella percezione può essere sbagliata, ma è davvero quello che ho percepito.
Avi Flax,

@Crazy Eddie Mi sono dimenticato di quell'uso, stavo pensando più all'uso più comune dei campi, stato. Modificherò la domanda.
Avi Flax,

Risposte:


14

Mi piacciono, purché il campo sia definitivo e venga utilizzato solo internamente nell'applicazione, non esposto in un'API per altre applicazioni. Ciò mantiene il codice più breve e più leggibile.

Non è necessario esporre i campi pubblici in un'API perché esponendo i campi pubblici, si espone anche l'implementazione. Se invece lo esponi come getXXX()metodo, potresti cambiare l'implementazione senza cambiare l'interfaccia API. Ad esempio, è possibile modificare e ottenere il valore da un servizio remoto, ma le applicazioni che utilizzano l'API non devono saperlo.

Questo è un progetto praticabile per i public finalcampi in classi immutabili .

Da Java efficace :

Articolo 14: nelle classi pubbliche, utilizzare metodi di accesso, non campi pubblici

... se una classe è pacchetto-privata o è una classe nidificata privata, non c'è nulla di intrinsecamente sbagliato nell'esporre i suoi campi di dati. Questo approccio genera meno disordine dell'approccio con il metodo accessor.

Sebbene non sia mai una buona idea per una classe pubblica esporre direttamente i campi, è meno dannoso se i campi sono immutabili.

Vedi anche Perché non dovrei usare POJO immutabili invece di JavaBeans?


Mi chiedo solo, quali sono i motivi per non esporlo in un'API?
Steven Jeuris,

2
@Steven: perché esponendo campi pubblici, si espone anche l'implementazione. Se invece lo esponi come getXXX()metodo, potresti cambiare l'implementazione senza cambiare l'interfaccia API. Ad esempio, è possibile modificare e ottenere il valore da un servizio remoto, ma le applicazioni che utilizzano l'API non devono saperlo.
Jonas,

@Jonas: quelli non sono generalmente candidati per le costanti in primo luogo.
Steven Jeuris,

@Steven: non sto parlando di costanti in primo luogo, ma di campi finali pubblici in classi immutabili . Ad esempio, perché non dovrei usare POJO immutabili invece di JavaBeans?
Jonas,

@Jonas: anche questo è un bell'uso! Forse è utile aggiornare un po 'la tua risposta per chiarire.
Steven Jeuris,

9

L'uso di coppie di metodi get / set è il tragico difetto del design storico. Non riesco a pensare a un altro linguaggio che implementa le proprietà in modo verbale e inefficiente.


1
Sebbene sia vero, questo è in qualche modo tangente al punto della domanda, che è (essenzialmente) quella data la scelta tra metodi set / get e campi pubblici, ci sono buone ragioni per preferire i campi in qualche situazione? Il fatto che altre lingue offrano soluzioni migliori al problema mi sembra irrilevante.
Jules,

5

Penso che i campi pubblici vadano bene per una classe che è essenzialmente un tipo di valore come un numero complesso o un punto, in cui la classe fa poco più che raggruppare insieme tipi primitivi come una struttura in stile C e forse definire alcuni operatori.


2
java.awt.Pointe gli amici sono un po 'un incubo.
Tom Hawtin - tackline il

@ TomHawtin-tackline: il problema Pointè che è ambiguo se si suppone che una variabile di tipo Pointincapsuli una posizione o debba incapsulare l'identità di un'entità con una posizione che può cambiare. Concettualmente, considererei il codice che passa in giro Pointmolto simile al codice che passa intorno agli array.
supercat il

Quindi se ottengo un Pointe lo modifico, dovrei aspettarmi che l'oggetto a cui fa riferimento si aggiorni in modo pulito sullo schermo? No, il problema Pointè che è mutabile. Avevamo String/ StringBufferma l'idea non sembrava riuscirci. / Il passaggio di matrici in giro ha problemi simili.
Tom Hawtin - affronta il

5

Per definire le costanti pubbliche è ancora utile. Per esempio

pubblico statico finale int DAYS_IN_WEEK = 7;

Tuttavia, preferisci ancora enum ove possibile. Per esempio

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

Per simulare semplici classi di strutture è anche utile. Nessun motivo per creare un getter e setter per ogni campo, quando sono comunque tutti pubblici.

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

Ma poi, molti direbbero che le strutture non hanno posto in un linguaggio come Java ...

1
@delnan: sono quasi gli stessi di JavaBeans, ma JavaBeans è molto più dettagliato e non sicuro per i thread. Vedi Perché non dovrei usare POJO immutabili invece di JavaBeans?
Jonas,

Alcune osservazioni specifiche per Android: gli enum sono più lenti da valutare rispetto agli ints e dovrebbero essere evitati. Inoltre, anche i campi a cui accedono frequentemente setter e getter in loop ristretti possono trarre vantaggio dall'essere pubblici.
Nailer,

2

Prima che gli IDE si diffondessero, rendere pubblici tutti i tuoi campi era un potente strumento per creare rapidamente prototipi / prove di concetti.

Oggi ci sono poche scuse per usarli, quando è possibile generare una coppia getter / setter con un clic del mouse.


4
Ma 10 public finalcampi sono più leggibili di 10 getXXX()metodi.
Jonas,

1
@Jonas Sì, ma non stiamo parlando di campi finali qui. Se anche i campi finali pubblici sono statici, sono costanti e una constparola chiave sarebbe sufficiente, se non sono statici, costituiscono una grave violazione dell'incapsulamento.
biziclop,

3
@biziclop secondo Wikipedia : "sebbene riservato come parola chiave in Java, const non è usato e non ha alcuna funzione"
Avi Flax,

@Avi Flax Sì, ma avrebbe potuto essere usato per contrassegnare le costanti, eliminando così la necessità di dichiarare le costanti come campi pubblici.
biziclop,

2
Supponendo che una coppia getter / setter sia del tutto appropriata, cioè. Spesso non lo è.
David Thornley,

2

Questo è soggettivo, ma la mia opinione è che l'intera nozione pubblica / privata sia superata e arretrata.

In Python non c'è pubblico / privato; tutto è fondamentalmente pubblico. Non ha causato molti problemi.

In Java si tende a creare getter / setter inutili per ogni campo per evitare il peccato di contrassegnarli come "pubblici". (IMHO se ti ritrovi a farlo, dovresti semplicemente contrassegnarli come pubblici).


Python ti consente di contrassegnare le cose come private prefissando i nomi con __. Non è privato al 100%, poiché ci sono ancora modi per accedere a tali variabili e metodi, ma in C # puoi fare cose simili con la riflessione.
Adam Lear
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.