L'origine di "un metodo dovrebbe restituire un valore o avere effetti collaterali, ma non entrambi"

12

Ho letto una volta che un metodo dovrebbe avere un valore di ritorno (e essere trasparente di riferimento), o avere effetti collaterali, ma non entrambi. Non riesco a trovare riferimenti a questa regola, ma voglio saperne di più.

Qual è l'origine di questo consiglio? Da quale persona o comunità è nato?

Credito extra: qual è il beneficio dichiarato di seguire questo consiglio?

    
posta Wayne Conrad 16.07.2015 - 20:03
fonte

3 risposte

13

Secondo Greg Young, questa idea è nata da Bertrand Meyer : Command- Separazione delle query .

It states that every method should either be a command that performs an action, or a query that returns data to the caller, but not both. In other words, Asking a question should not change the answer.1 More formally, methods should return a value only if they are referentially transparent and hence possess no side effects.

1: Eiffel: a language for software engineering slide 43-48

In Domain Driven Design, questo è simile a Command-Query-Read Separation / Segregation (CQRS), come indicato da Greg Young.

Greg Young ha preso l'idea di CQS da Bertrand per nominare CQRS come menzionato da Martin Fowler in questo articolo CQRS

vantaggi

  • La parte Lettura (Query) può essere ridimensionata / ottimizzata in modo diverso dalla parte Write (comando). Separare i due impedirebbe di intralciare reciprocamente quando ottimizzazione / prestazioni sono la chiave.

Leggi l'articolo nel link di Martin Fowler per ulteriori informazioni.

    
risposta data 16.07.2015 - 20:51
fonte
4

Non so da dove provenga, ma è un buon consiglio e abbastanza semplice da capire.

Qualsiasi programma progettato con cura verrà suddiviso in varie parti, combinato e composto in vari modi. Più è difficile ragionare su cosa fa una particolare parte, più difficile sarà assicurarsi che il tuo programma reagisca in modo prevedibile.

Isolare le parti che producono effetti collaterali rende il resto più facile da ragionare, testare e eseguire il debug. Ridurre il numero di effetti collaterali in ciascuna parte che genera un effetto collaterale renderà la parte più facile da lavorare allo stesso modo.

Se lo decomponi ulteriormente, un valore di ritorno è un effetto. Gli effetti collaterali sono un effetto. Una funzione dovrebbe produrre solo 1 effetto (se possibile) perché maggiore è il numero di input e effetti di una funzione, maggiore è la difficoltà nel ragionamento su ciò che effettivamente fa.

    
risposta data 16.07.2015 - 20:36
fonte
1

Extra credit: What is the originally claimed benefit of following this advice?

Uno dei vantaggi di separare il valore di ritorno dagli effetti collaterali è che rimuove un potenziale problema che potrebbe essere causato da short- valutazione del circuito .

bool FooWithSideEffect() {
    // do query
    // do side effect
    return resultOfQuery;
}

bool BarWithSideEffect() {
    // do query
    // do side effect
    return resultOfQuery;
}

void BadShortCircuitEvaluation()
{
    // the programmer's intent is to have side effects of both functions
    if (FooWithSideEffect() && BarWithSideEffect() ) {
        // do something
    }

    // in case FooWithSideEffect() returns true, 
    // then BarWithSideEffect() is not called at all
    // because of short-circuit evaluation
}
    
risposta data 16.07.2015 - 21:00
fonte

Leggi altre domande sui tag