Campi di accesso di super classe da classi derivate [duplicato]

0

Esiste una classe BaseGame astratta che verrà ereditata da specifiche classi di gioco.

Questa classe ha un attributo requestHandler che sarà usato in tutte le sottoclassi e dovrebbe essere inizializzato nel costruttore, quindi metto questo costruttore in superclasse.

È meglio (ha più senso) mantenere requestHandler privato (caso 1) e accedervi in sottoclassi via accessors o renderlo protetto (caso 2) e accedervi direttamente? Ci sono implicazioni nell'uso del caso 1 o caso 2, o semplicemente non importa?

case1:

public abstract class BaseGame {

    private RequestHandler requestHandler;

    protected BaseGame(RequestHandler requestHand) {
        this.requestHandler = requestHand;
    }

    protected RequestHandler getRequestHandler() {
        return requestHandler;
    }
}

public class SoccerGame extends BaseGame {

    public SoccerGame(RequestHandler requestHand) {
        super(requestHand);
    }    

    public void doSoccerGame() {
        getRequestHandler().submitScore(10);
    }

}

caso 2:

public abstract class BaseGame {

    protected RequestHandler requestHandler;

    protected BaseGame(RequestHandler requestHand) {
        this.requestHandler = requestHand;
    }
}

public class SoccerGame extends BaseGame {

    public SoccerGame(RequestHandler requestHand) {
        super(requestHand);
    }    

    public void doSoccerGame() {
        requestHandler.submitScore(10);
    }
}
    
posta alexpfx 21.04.2015 - 20:27
fonte

1 risposta

3

Contrariamente alla credenza popolare, i metodi di accesso non offrono alcun grande vantaggio sugli accessi diretti al campo, mentre in java tendono a ingombrare il codice con un sacco di get se () s. (Confronta con C #, che ha una caratteristica fantastica chiamata proprietà, che assomigliano a campi ma si comportano come accessors, salvandoti da tutti i mindless getSuchAndSuch() se setSuchAndSuch() s.)

Tuttavia, "nessun grande vantaggio" non significa assolutamente alcun vantaggio. I vantaggi dell'utilizzo di metodi accessor invece dell'accesso diretto al campo sono i seguenti:

  1. Se è necessario mantenere la compatibilità binaria, è necessario utilizzare metodi accessor, in modo che la classe contenente i campi possa essere modificata senza codice di interruzione che è già stato scritto per utilizzare la classe. (Compatibilità binaria significa compatibilità senza la necessità di modificare e ricompilare una delle due parti. Poiché stai scrivendo sia la classe base che i suoi discendenti, questo non è applicabile a te.)

  2. I metodi accessor sono spesso inevitabili, mentre l'accesso diretto al campo non è mai inevitabile, quindi andare con la dottrina "usa sempre gli accessor" semplifica le cose e introduce l'omogeneità sull'intero codebase.

  3. Durante il refactoring del codice che prova vari scenari what-if, a volte si scopre di avere un campo che deve essere sostituito da un calcolo, che a sua volta significa che deve essere incapsulato da un metodo accessor, e a volte si scopre di avere un campo che memorizza il risultato di un calcolo e quindi non deve essere nascosto dietro un metodo di accesso, quindi l'accessor può andare e il campo può essere reso protetto o pubblico. Se continui a fare questo tipo di refactoring molto, potresti arrivare ad un punto in cui potresti dire "aw, dimenticalo!" e nascondi tutti i campi dietro i metodi di accesso in modo che tu non debba continuare a refactoring più classi rispetto a quella su cui stai lavorando.

  4. Quando si scrive codice in java e si utilizza un IDE decente, quando si dispone di un oggetto e si desidera ottenere qualcosa da esso, si tende a digitare myObject.get e poi l'IDE mostra un elenco di completamento automatico opzioni, in modo da avere tutto ciò che puoi "ottenere" dall'oggetto proprio di fronte a te. Se usi i campi, devi fermarti a myObject. e sfogliare un elenco che contiene tutto, non solo le cose che possono essere ottenute dall'oggetto. Lo stesso vale con myObject.set quando vuoi impostare qualcosa.

In entrambi i casi, vorrei che mai rendesse un campo non finale tutt'altro che privato. Fortunatamente, nel tuo caso, il tuo requestHandler sembra essere un candidato ideale per essere definitivo, (probabilmente viene impostato solo nel costruttore e mai più), quindi è abbastanza legittimo renderlo definitivo e protetto.

    
risposta data 21.04.2015 - 21:02
fonte