JavaBeans è un buon esempio di incapsulamento?

6

Sto cercando di capire se JavaBeans è un buon esempio di incapsulamento. A mio avviso, è non come di solito tutti gli stati interni vengono esposti tramite getter e setter.

Un semplice esempio è

public class Test {
    private List<String> names = new ArrayList<String>();

    public List<String> getNames() {
        return names;
    }

    public void setNames(List<String> names) {
        this.names = names;
    }
}

Questo segue lo standard JavaBeans ma perde l'implementazione. Ad esempio, un utente potrebbe chiamare test.getNames().clear() .

Mi manca qualcosa?

    
posta Augusto 26.10.2011 - 11:20
fonte

4 risposte

10

L'incapsulamento è un'espressione sovraccaricata, quindi definiamolo prima. Secondo l'encapsulation Wikipedia si riferisce a due concetti:

In a programming language encapsulation is used to refer to one of two related but distinct notions, and sometimes to the combination thereof:

  1. A language mechanism for restricting access to some of the object's components.

  2. A language construct that facilitates the bundling of data with the methods (or other functions) operating on that data.

Direi che la tipica classe JavaBeans soddisfa la seconda definizione ma quasi mai la prima , quindi suppongo che lo standard JavaBeans non sia un buon esempio di quella particolare nozione di incapsulamento.

Forse leggermente fuori tema, ma spiegando perché qualcosa che inizia con class nel codice non è necessariamente sempre una classe in senso più astratto. Ho trovato una buona definizione di class e data structure in Pulisci codice . Sfortunatamente non ho il libro qui, quindi ho bisogno di recitare dall'alto della mia testa:
  • Un class incapsula il suo stato, offrendo solo metodi sensibili e mostrando lo stato solo dove è necessario.
  • Un data structure espone completamente il suo stato, non tentando di nascondere nulla dal mondo esterno

Una classe implementata secondo lo standard JavaBeans sarebbe un data structure secondo la definizione di cui sopra. Questo forse spiega perché è un class nel codice, ma in realtà non è una classe che soddisfa l'incapsulamento.

    
risposta data 26.10.2011 - 11:33
fonte
7

Hai ragione. Questo non è un buon esempio, e in effetti controllori di codice come ad es. FindBugs lo contrassegnerà esplicitamente ("L'oggetto espone l'implementazione restituendo un riferimento al campo mutabile"). Non è abbastanza così male come i campi pubblici - un'implementazione getter / setter potrebbe un giorno essere sostituita da un'implementazione che fa più logica di adesso, ad es. validazione, registrazione, ecc., e quindi i client riceverebbero il vantaggio senza essere ricompilati, ma anche questo non impedirà alle persone di affidarsi alla semantica di getNames () che è mutabile.

Un semplice esempio di incapsulamento è Collections.sort() . Decenni di conoscenza accumulata sulle prestazioni e sui compromessi tempo / spazio, algoritmi sofisticati che la maggior parte dei programmatori potrebbe probabilmente sbagliare in modo subitaneo se dovessero scrivere da soli ... ed è tutto tuo per il prezzo di una chiamata al metodo! Cerca di emulare sort() , non getNames() nel tuo codice.

    
risposta data 26.10.2011 - 11:31
fonte
4

usually all the internal state is exposed through getters and setters.

Potrebbe essere il caso più comune, ma di solito il punto di incapsulamento è "fornire un'interfaccia pubblica dietro la quale possiamo cambiare le cose secondo necessità" piuttosto che "proteggere i dettagli dell'implementazione come se fossero il tuo primogenito seduto su un vasino in oro massiccio ".

Se risulta che lo stato interno deve essere protetto dalla manipolazione, puoi facilmente cambiare il getter per restituire una copia difensiva o un wrapper di sola lettura.

E si noti che il vero punto dello standard JavaBeans è che il getter e il setter non necessariamente accedono a un campo privato - possono anche convertire da e verso un campo in un formato diverso , puoi avere solo un getter per una proprietà di sola lettura derivata, o qualsiasi altra cosa tu possa immaginare.

Quindi io dico che in realtà sì, lo standard Java Beans è un buon esempio per l'incapsulamento, anche se il tipico JavaBean potrebbe non esserlo.

    
risposta data 26.10.2011 - 11:37
fonte
1

I JavaBeans non hanno alcuna attività menzionata nel contesto di concetti orientati agli oggetti come l'incapsulamento.

L'incapsulamento si riferisce al contenimento delle funzionalità dietro a api - nei linguaggi orientati agli oggetti, l'API viene tipicamente fornita da una classe attraverso i suoi membri pubblici. L'incapsulamento consente di riutilizzare facilmente le funzionalità senza causare l'associazione di annullamento perché, ancora, la funzionalità è accessibile tramite un'API, mai direttamente.

Come qualcuno menzionato sopra, un oggetto per definizione si trova quando i dati e il codice che operano su di esso si trovano nella stessa classe. Nel 99,9% dei casi che ho visto utilizzare JavaBeans (che sfortunatamente è ovunque), non contengono alcuna funzionalità diversa da setter e getter. Setter e getter non sono funzionalità a livello di applicazione, ovvero non si intende salvare una fattura chiamando un setter o un getter, quindi i bean non sono oggetti.

I bean sono struct, che sono strutture solo dati utilizzate nella programmazione strutturata e procedurale. Erano lo stato dell'arte alla fine degli anni '80, all'inizio degli anni '90, utilizzando quasi tutte le lingue disponibili al momento, il più popolare è C.

L'uso dei bean renderà i tuoi programmi molto più grandi e molto meno flessibili rispetto, ad esempio, all'utilizzo di raccolte in luoghi appropriati. Tutti quelli di cui parlo con schifo a questa nozione, ma se non sbaglio, le classi di Java compilate, sotto il cofano, sono fondamentalmente raccolte di collezioni. Queste raccolte sono ciò che la riflessione troll attraverso per ottenere informazioni sulla classe. Sono ciò che il runtime guarda attraverso per trovare il metodo corretto da eseguire per una determinata classe.

Un bean è, senza dubbio, un'automazione poco amichevole che puoi ottenere - sono assolutamente inflessibili e faranno crescere il tuo codice base ben oltre la funzionalità che contiene.

    
risposta data 22.06.2013 - 07:09
fonte

Leggi altre domande sui tag