Cosa fare con i campi privati con getter e setter in Java [duplicato]

5

Quando Getters e Setters sono giustificati è una domanda eccellente che si concentra sull'utilizzo di getter e setter come parte dell'interfaccia esterna.

Quello con cui sto combattendo è ... avendo getter e setter ci sono ora diversi modi per aggiornare lo stato dell'oggetto, dato che i campi privati possono essere aggiornati direttamente bypassando il setter o possono essere aggiornati dal setter.

Prendi l'esempio seguente ... _size è il campo privato e ha due metodi getSize() e setSize(int size) . Se incrementare _size è codificato come il metodo increment , tutto è buono. D'altra parte, l'utilizzo di increment2 può mettere Ordine in uno stato illegale.

C'è un modo per impedire agli sviluppatori di aggirare accidentalmente il getter / setter e utilizzare direttamente i campi privati !? In caso contrario, quale convenzione dovrebbe essere utilizzata per garantire che l'oggetto non venga mai messo in uno stato non valido?

public class Order {

    private int _size = 0;

    public int getSize() {
        return _size;
    }

    public void setSize(int size) { 
        if (_size < 0)
             throw IllegalArgumentException("...")

        _size = size; 
    }

    public void increment(int increment) {
        setSize(getSize() + increment);
    }

    public void increment2(int increment) {
        _size = _size + increment;
    }



 }
    
posta Dakotah North 22.05.2011 - 20:11
fonte

2 risposte

2

In primo luogo, di solito non dovresti avere getter e setter pubblici. Un oggetto dovrebbe fornire un'interfaccia di livello superiore che non richiede che gli oggetti esterni stiano cambiando, anche con la convalida, lo stato interno dell'oggetto. In questo modo se il tuo oggetto cambia gli altri oggetti non dovrebbe anche essere necessario cambiare.

Per questo motivo, il tuo metodo di incremento è una buona idea mentre la funzione setSize non lo è. Semplicemente non dovresti fornire un'interfaccia di basso livello.

In secondo luogo, l'intero oggetto è responsabile del mantenimento dello stato interno. Nel tuo caso semplice sopra probabilmente scriverei:

void increment(int amount)
{
     if(amount < 0) throw new InvalidArgumentError("amount must not be negative");
     _size += amount;
}

Penso che rilevare gli argomenti del metodo non validi sia meglio che controllare l'invalidazione dello stato. In questo modo la tua interfaccia esterna si concentra su ciò che sei autorizzato a fare con un oggetto invece di come evitare di produrre uno stato interno non valido.

In terzo luogo, può avere senso convalidare il tuo oggetto per assicurarti che nessun bug abbia introdotto incongruenze in esso. Tuttavia, il modo migliore per eseguire tale compito dipende in realtà dagli strumenti che il tuo linguaggio ti offre. Tuttavia, penso che provare a usare setter per questo abbia problemi.

L'uso dei setter introduce un sacco di codice aggiuntivo per chiamarli. Di conseguenza, tutto il tuo codice diventa difficile da leggere.

A volte gli invarianti dipendono da due valori. Ad esempio, un C ++ std :: vector deve avere la sua capacità () > = size (). Se cerchi di proteggere setSize () e setCapacity (), quale controlla che la dimensione sia maggiore?

Inoltre, gli oggetti diventano spesso non validi durante l'elaborazione della logica interna prima di diventare nuovamente validi. Un setter controlla l'oggetto ad ogni incarico, ma tu vuoi veramente il controllo dopo che il metodo pubblicamente chiamato è stato completato.

    
risposta data 22.05.2011 - 22:44
fonte
6

I getter e i setter sono per utenti esterni della tua API

Naturalmente una classe può accedere al loro stato interno e cambiarla se necessario. Non hanno bisogno di passare attraverso un setter. Il modello è progettato come misura difensiva per gli utenti esterni del tuo codice. Idealmente, il getter fornisce un clone dello stato interno e il setter fornisce la convalida per garantire che venga mantenuto lo stato interno valido.

    
risposta data 22.05.2011 - 21:28
fonte

Leggi altre domande sui tag