Dove inseriamo il codice "chiedendo al mondo" quando separiamo il calcolo dagli effetti collaterali?

10

In base al principio di separazione della query di comando , nonché Thinking in Data e DDD con Clojure presentazioni si dovrebbero separare gli effetti collaterali (modificando il mondo) da calcoli e decisioni, in modo che sia più facile comprendere e testare entrambe le parti.

Questo lascia una domanda senza risposta: dove relativamente al confine dovremmo mettere "chiedendo al mondo"? Da un lato, la richiesta di dati da sistemi esterni (come database, API di servizi estenziali, ecc.) Non è referentially transparent e quindi non dovrebbe stare insieme al puro codice computazionale e decisionale. D'altra parte, è problematico, o forse impossibile, separarli dalla parte computazionale e passarla come argomento perché non possiamo sapere in anticipo quali dati potremmo aver bisogno di richiedere.

    
posta Alexey 02.11.2013 - 14:38
fonte

2 risposte

1

On the other hand, it's problematic, or maybe impossible to tease them apart from computational part and pass it as an argument as because we may not know in advance which data we may need to request.

Questa è un'istanza in cui, come notato nei commenti, passando la capacità di recuperare i dati (ad esempio, la funzione di prima classe, un oggetto che implementa un'interfaccia, ecc.) fornisce un comodo meccanismo per isolare gli effetti collaterali.

Una funzione di ordine superiore il cui corpo è puro ha una purezza non fissata: link

Ne ho parlato, definendo questo tipo di funzione una funzione potenzialmente pura: link

Se si combina una funzione potenzialmente pura con funzioni fall-through (che mancano di costrutti ramificati e fanno il meno possibile), una combinazione che io chiamo insiemi di isolamento, è possibile isolare gli effetti collaterali in modo abbastanza efficace e creare codice molto verificabile: link

    
risposta data 15.01.2014 - 07:51
fonte
0

Memorizzi il risultato nella classe, all'inizio sembra un po 'strano, ma risulta in un codice più semplice. per esempio. nessuna variabile temporanea nel chiamante.

class database_querier
    feature -- queries
        was_previous_query_ok : boolean is
            do
                Result = …
            end

        previous_query_result : string is 
            requires
                was_previous_query_ok
            do
                Result = query_result
            end

    feature -- commands
        query_db (…) is
            do
                …
                query_result = bla
            end

    feature {none} --data
        query_result : string
    
risposta data 15.11.2013 - 11:07
fonte