Domanda

È mai appropriato abbandonare " getMyValue () " e " setMyValue () " modello di getter e setter se nomi di funzioni alternative rendono l'API più ovvia?

Ad esempio, immagina di avere questa classe in C ++:


public class SomeClass {
private:
    bool mIsVisible;

public:
    void draw();
    void erase();
}

Potrei aggiungere funzioni per ottenere / impostare " mIsVisible " in questo modo:


bool getVisible() { return mIsVisible; };

void setVisible(bool visible) { if (!mIsVisible && visible) { draw(); } else if (mIsVisible && !visible) { erase(); }

mIsVisible = visible;

}

Tuttavia, sarebbe ugualmente possibile utilizzare i seguenti metodi:


bool isVisible() { return mIsVisible; };

void show() { 
    if (!mIsVisible) {
        mIsVisible = true;
        draw();
    }
}

void hide() {
    if (mIsVisible) {
        mIsVisible = false;
        erase();
    }
}

In breve, è meglio avere un singolo "setVisible (bool)" metodo o una coppia di " show () " e " hide () " metodi? Esiste una convenzione o è puramente soggettiva?

È stato utile?

Soluzione

Leggi l'articolo " Dillo, non chiedere " sul sito di Pragmatic Programmers e penso che vedrai che il secondo esempio è la strada da percorrere.

Fondamentalmente, non dovresti diffondere la logica attraverso il tuo codice che è implicito nel tuo primo esempio, vale a dire:

  1. ottieni il valore di visibilità corrente,
  2. prendere una decisione in base al valore,
  3. aggiorna oggetto.

Altri suggerimenti

Nell'esempio che hai fornito, show () e hide () hanno molto senso, almeno per me.

D'altra parte, se avevi una proprietà skinPigment e hai deciso di creare funzioni chiamate tanMe () e makeAlbino () che sarebbe una scelta davvero scadente, non ovvia.

È soggettivo, devi provare a pensare come pensano i tuoi utenti (le persone che utilizzano questa classe). Qualunque sia il modo in cui decidi, dovrebbe essere ovvio per loro e ben documentato.

Vorrei andare con il set isVisible () / show () / hide ().

setVisible () implica che tutto ciò che fa cambia la variabile interna. show () e hide () rendono chiari gli effetti collaterali.

D'altra parte, se tutto getVisible () / setVisible () ha fatto era per cambiare la variabile interna, allora hai appena cambiato notevolmente poco dal fatto di averli come campi pubblici.

i setter in realtà hanno ben poco a che fare con l'orientamento agli oggetti, che è il linguaggio di programmazione applicato nell'esempio. i getter sono leggermente migliori, ma possono essere vissuti senza in molti casi. Se tutto può essere ottenuto e impostato, che senso ha avere un oggetto? Le operazioni dovrebbero essere invocate sugli oggetti per realizzare le cose, cambiare lo stato interno è solo un effetto collaterale di questo. La cosa brutta di un setter in presenza di polimorfismo - uno dei cardini di OO - è che costringi ogni classe derivata ad avere un setter. Cosa succede se l'oggetto in questione non ha bisogno di uno stato interno chiamato mIsVisible? Sicuro che può ignorare la chiamata e implementare come vuoto, ma poi ti rimane un'operazione senza significato. OTOH, operazioni come show and hide possono essere facilmente ignorate con diverse implementazioni, senza rivelare nulla sullo stato interno.

In generale, penso che setter / getter dovrebbero solo impostare i valori delle proprietà. Nel tuo esempio, stai anche eseguendo un'azione in base al valore della proprietà isVisible. In questo caso, direi che usare le funzioni per eseguire l'azione e aggiornare lo stato è meglio che avere un setter / getter che esegue un'azione come effetto collaterale dell'aggiornamento della proprietà.

Se la commutazione di mIsVisible attiva e disattiva immediatamente la visibilità dell'oggetto, utilizzare lo scenario mostra / nascondi. Se rimarrà un po 'più a lungo nel vecchio stato (ad es. Fino a quando qualcos'altro non avvierà un ridisegno), lo scenario set / get sarebbe la strada da percorrere.

Preferisco i metodi show () e hide () perché dicono esplicitamente cosa stai andando. SetVisible (booleano) non ti dice se il metodo mostrerà / disegnerà immediatamente. Inoltre show () e hide () sono metodi meglio denominati per un'interfaccia (IMHO).

Implicitamente, le funzioni 'show' e 'hide' che elenchi sono entrambi setter

Per i booleani, penso che un singolo strumento come quello che hai mostrato sarebbe buono. Tuttavia, anche una funzione .show e .hide sembrano comandi, non funzioni che cambiano lo stato dell'oggetto.

Nel caso in cui devi effettivamente scrivere codice come

if (shouldBeShowingAccordingToBusinessLogic()) w.show();
else w.hide();

ovunque, potresti stare meglio con

w.showIfAndOnlyIf(shouldBeShowingAccordingToBusinessLogic())

O, per casi veramente bizzarri, quando la tua logica non può decidere se mostrare o meno fino alla fine di un po 'di codice, puoi provare

w.setPostponedVisibility(shouldBeShowingAccordingToBusinessLogic());
...
w.realizeVisibility();

(Non ho detto che è bizzare?)

Un'ulteriore motivazione per la soluzione display / hide è quella come setter,

il metodo setVisible ha un 'effetto collaterale', in quanto mostra o nasconde anche SomeClass . I metodi display / hide trasmettono meglio l'intento di ciò che accade.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top