Convenzione di denominazione per un metodo che imposta e ottiene

2

Diciamo che abbiamo un metodo setFoo che imposta un flag in un oggetto Bar, ad es.

class Baz { 
    public void setFoo(String foo)(
       ...
    }
}

all'interno di setFoo, il metodo sta facendo un costoso caricamento dell'oggetto Bar dal database.

class Baz { 
    public void setFoo(String foo)(
       Bar bar = expensiveGetBar();
       ...
    }
}

Per evitare di dover recuperare nuovamente l'oggetto Bar , lo sviluppatore cambia il metodo per restituirlo.

class Baz { 
    public Bar setFoo(String foo)(
       Bar bar = expensiveGetBar();
       ...
       return bar;
    }
}

Le domande sono:

  1. Questo è scoraggiato?
  2. Se sì, perché e qual è l'alternativa
  3. La soluzione dovrebbe invece aggiungere una sorta di cache?
  4. Come prefiggesti il metodo? impostato? ottenere? seget? geset?
posta Eran Medan 08.02.2013 - 07:35
fonte

4 risposte

10

Una funzione dovrebbe servire a uno scopo. Questo fa parte del motivo per cui è chiamato una funzione. Se trovi un metodo difficile da nominare perché sta facendo più di una cosa, quindi dividerlo in più di un metodo. I nomi dei metodi leggibili possono essere fatti spesso da un solo verbo e un solo nome.

Nel tuo esempio, potresti modificare setFoo() per prendere esplicitamente una Bar . Come setter, non dovrebbe davvero bisogno di restituire nulla. Quindi esporre expensiveGetBar() o esporre getBar() e memorizzare nella cache il risultato di expensiveGetBar() .

    
risposta data 08.02.2013 - 07:49
fonte
3

Ecco la mia soluzione preferita per questo problema:

class Baz { 
    Bar _bar;

    /* make this public if you like */ 
    Bar getBar()
    {
       if(_bar==null)
           _bar = expensiveGetBar();
       return _bar;
    }

    public void setFoo(String foo)
    {
       Bar bar = getBar();
       ...
    }
}

Potrebbe essere necessario aggiungere un metodo per cancellare o aggiornare _bar , ma ciò dipende dal tuo caso reale.

    
risposta data 08.02.2013 - 14:10
fonte
2

Getter e Setter sono un mezzo per esporre le proprietà delle classi. Sono funzioni a senso unico. Possono ottenere (restituire un valore) o impostare (accettare un valore), ma non eseguono entrambi la stessa funzione. Anche le proprietà C # che eliminano le funzioni get get e set mantengono l'operazione a senso unico.

Quindi se ho

  • GetFoo()
  • SetFoo()

Quindi c'è un'operazione implicita su una proprietà chiamata Foo . A causa della magia dell'incapsulamento, non mi interessa care se l'oggetto interno è chiamato Foo . So solo che se ho SetFoo() e poi GetFoo() allora ci dovrebbe essere un certo grado di collegamento logico tra le mie operazioni.

Quindi non hai getter | setter nel tuo esempio. Sì, so che sono chiamati così, ma non è quello che stanno facendo. Il terzo frammento mostra davvero la deviazione dal concetto di proprietà. public Bar setFoo(String foo) significa che ho impostato un Foo ma ottengo un Bar indietro? Cosa?!

È necessario selezionare un verbo diverso da "Imposta" da utilizzare in questo caso, poiché la funzione non sta eseguendo un'operazione impostata. Qualcosa come public Bar AnalyzeFoo(String foo) può essere una descrizione più appropriata di ciò che sta facendo la funzione e nasconde ancora il fatto che c'è un'operazione molto costosa su Bar come parte della funzione.

Un esempio più concreto può aiutare.

Questo prossimo esempio è negativo, per i motivi spiegati sopra:
public ProfitMargin SetInvoice(Invoice inv)

Ma questo esempio ha più senso:
public ProfitMargin AnalyzeInvoice(Invoice inv)

Non so o non ho bisogno di sapere quanto è costosa un'operazione per separare il Invoice e identificare il margine di profitto; la funzione AnalyzeInvoice() si occupa di questo per me.

Una breve nota su cosa intendevo per le proprietà C # ...

Sì, devo ancora definire il get & imposta le routine ma sono espresse come parte della proprietà e non richiedono funzioni aggiuntive come Java usato per richiedere.

Quindi in C #, ho:

private ____ xyz
public ____ MyProp {
   get { .... return xyz; }
   set { .... xyz = value; }
}

Mentre la vecchia scuola Java richiedeva funzioni esplicite:

private ____ xyz;
public ____ GetMyPrep() { ... return xyz; }
public void SetMyPrep(____ value) { ... xyz = value; }

Entrambi funzionano bene e gli IDE moderni semplificano il getter | creazione setter. Il punto è che entrambi gli approcci sono ancora operazioni a senso unico.

    
risposta data 08.02.2013 - 13:08
fonte
2

Penso che potresti fare quanto segue:

    bar = getExpensiveBar();
    setBarState(bar);

    setBarState( Bar myBar)
    {
       myBar.setFlag(true);
       myBar.setOtherFlag(false);
    }

Ma se l'oggetto Bar ha solo un flag, non dovresti fare solo quanto segue:

    bar = getExpensiveBar();
    bar.setFlag(true);
    
risposta data 08.02.2013 - 13:58
fonte

Leggi altre domande sui tag