Onde colocamos o código "perguntando ao mundo" quando separamos a computação dos efeitos colaterais?


10

De acordo com o princípio de Separação de Consulta por Comando , assim como as apresentações Thinking in Data e DDD with Clojure, é necessário separar os efeitos colaterais (modificando o mundo) dos cálculos e decisões, para que seja mais fácil entender e testar as duas partes.

Isso deixa uma pergunta sem resposta: onde relativamente à fronteira devemos colocar "perguntar ao mundo"? Por um lado, a solicitação de dados de sistemas externos (como banco de dados, APIs de serviços extental etc.) não é referencialmente transparente e, portanto, não deve se encaixar no código computacional e de tomada de decisão. Por outro lado, é problemático ou talvez impossível separá-los da parte computacional e transmiti-los como argumento, porque talvez não saibamos antecipadamente quais dados podemos precisar solicitar.


1
É aí que entram os conceitos de retorno de chamada. Se você não souber de antemão quais dados podem ser necessários, forneça um retorno de chamada para o código computacional onde ele pode especificar quais dados precisam e faça com que as outras camadas façam a busca e o fornecimento reais . Se precisar ser assíncrono, o retorno de chamada pode até especificar outra função para chamar com os dados buscados quando estiverem disponíveis.
Marjan Venema

1
@MarjanVenema, esta é a única opção que me vem à cabeça. Apenas do ponto de vista teórico: se o método, sem nenhum efeito colateral, invocar um retorno de chamada com efeito colateral, ele se torna colateral. Provavelmente, meu problema aqui é que presumo que o cálculo da separação dos efeitos colaterais exija que o cálculo seja referencialmente transparente. Embora não seja necessário verdade.
Alex13 #

1
Se essa é a sua preocupação, seu cálculo simplesmente não é suficiente. Você precisa abstrair a tomada de decisão sobre quais outros dados / etapas são necessários. Portanto, divida a computação completa em etapas com base em onde as decisões são tomadas e quais dados são necessários. Depois, tenha algum tipo de "diretor" que gerencia o fluxo de trabalho para a computação completa: iniciando cada etapa, recuperando informações de cada etapa, usando isso para decidir a próxima etapa e os dados necessários, iniciando um processo de busca para obtê-lo e depois passando os dados buscados para a próxima etapa do cálculo.
Marjan Venema

Respostas:


1

Por outro lado, é problemático ou talvez impossível separá-los da parte computacional e transmiti-los como argumento, porque talvez não saibamos antecipadamente quais dados podemos precisar solicitar.

Essa é uma instância em que, conforme observado nos comentários, a capacidade de recuperar dados (por exemplo, função de primeira classe, um objeto que implementa uma interface etc.) fornece um mecanismo conveniente para isolar efeitos colaterais.

Uma função de ordem superior cujo corpo é puro possui pureza não corrigida: http://books.google.com/books?id=Yb8azEfnDYgC&pg=PA143#v=onepage&q&f=false

Eu escrevi sobre isso, chamando esse tipo de função de potencialmente pura: http://adamjonrichardson.com/2014/01/13/potentially-pure-functions/

Se você combinar uma função potencialmente pura com funções fall-through (que não possuem construções de ramificação e fazem o mínimo possível), uma combinação que eu chamo de conjuntos de isolamento, você pode isolar os efeitos colaterais com bastante eficiência e criar código muito testável: http: // adamjonrichardson.com/2014/01/15/isolating-side-effects-using-isolation-sets/


0

Você armazena o resultado na classe, isso parece um pouco estranho a princípio, mas resulta em um código mais simples. por exemplo, nenhuma variável temporária no chamador.

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

1
Adoro ver eiffel na natureza.
SBI 14/01

@sbi é apenas pseudo-código. :-)
ctrl-alt-delor 14/01

Perto o suficiente para me fazer feliz;)
SBI
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.