Di mana kita meletakkan kode "meminta dunia" ketika kita memisahkan perhitungan dari efek samping?

10

Menurut prinsip Pemisahan Perintah-Kueri , serta Berpikir dalam Data dan DDD dengan presentasi Clojure seseorang harus memisahkan efek samping (memodifikasi dunia) dari perhitungan dan keputusan, sehingga akan lebih mudah untuk memahami dan menguji kedua bagian.

Ini menyisakan pertanyaan yang tidak terjawab: di mana relatif terhadap batas yang harus kita letakkan "bertanya kepada dunia"? Di satu sisi, meminta data dari sistem eksternal (seperti basis data, API layanan eksternal, dll.) Tidak transparan secara referensi dan karenanya tidak boleh duduk bersama dengan kode komputasi dan pengambilan keputusan murni. Di sisi lain, itu bermasalah, atau mungkin mustahil untuk menggoda mereka selain dari bagian komputasi dan meneruskannya sebagai argumen karena kita mungkin tidak tahu sebelumnya data mana yang mungkin perlu kita minta.

Alexey
sumber
1
Di situlah konsep panggilan balik masuk. Jika Anda tidak tahu sebelumnya data apa yang mungkin diperlukan, berikan panggilan balik ke kode komputasi di mana ia dapat menentukan data apa yang dibutuhkan, dan minta lapisan lain melakukan pengambilan dan penyediaan aktual . Jika perlu asinkron, callback bahkan dapat menentukan fungsi lain untuk memanggil dengan data yang diambil ketika sudah tersedia.
Marjan Venema
1
@MarjanVenema, ini adalah satu-satunya pilihan yang muncul di pikiran saya juga. Hanya dari sudut pandang teoretis: jika metode, jika tidak ada efek samping, memanggil panggilan balik efek-efektif, metode tersebut akan menjadi efek samping. Mungkin masalah saya di sini adalah saya berasumsi bahwa perhitungan pemisahan dari efek samping memerlukan perhitungan yang transparan transparan. Padahal itu tidak perlu benar.
Alexey
1
Jika itu yang Anda khawatirkan, perhitungan Anda tidak akan cukup. Anda perlu mengabstraksi pengambilan keputusan tentang data / langkah apa yang dibutuhkan. Jadi pisahkan perhitungan lengkap dalam langkah-langkah berdasarkan di mana keputusan dibuat untuk data apa yang dibutuhkan. Kemudian miliki semacam "sutradara" yang mengelola alur kerja untuk perhitungan lengkap: memulai setiap langkah, mendapatkan kembali informasi dari setiap langkah, menggunakannya untuk memutuskan langkah berikutnya dan data yang diperlukan, memulai proses pengambilan untuk mendapatkannya dan kemudian meneruskan data yang diambil ke langkah selanjutnya dalam perhitungan.
Marjan Venema

Jawaban:

1

Di sisi lain, itu bermasalah, atau mungkin mustahil untuk menggoda mereka selain dari bagian komputasi dan meneruskannya sebagai argumen karena kita mungkin tidak tahu sebelumnya data mana yang perlu kita minta.

Ini adalah contoh di mana, seperti disebutkan dalam komentar, memberikan kemampuan untuk mengambil data (misalnya, fungsi kelas satu, objek yang mengimplementasikan antarmuka, dll.) Menyediakan mekanisme yang nyaman untuk mengisolasi efek samping.

Fungsi tingkat tinggi yang tubuhnya murni memiliki kemurnian yang tidak tetap: http://books.google.com/books?id=Yb8azEfnDYgC&pg=PA143#v=onepage&q&f=false

Saya sudah menulis tentang ini, menyebut jenis fungsi ini fungsi yang berpotensi murni: http://adamjonrichardson.com/2014/01/13/potential-pure-functions/

Jika Anda menggabungkan fungsi yang berpotensi murni dengan fungsi jatuh (yang tidak memiliki konstruksi bercabang dan melakukan sesedikit mungkin), kombinasi yang saya sebut set isolasi, Anda dapat mengisolasi efek samping dengan cukup efektif dan membuat kode yang sangat dapat diuji: http: // adamjonrichardson.com/2014/01/15/isolating-side-effects-using-isolation-sets/

Adam
sumber
0

Anda menyimpan hasilnya di kelas, ini agak aneh pada awalnya, tetapi menghasilkan kode yang lebih sederhana. misalnya tidak ada variabel sementara di pemanggil.

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
ctrl-alt-delor
sumber
1
Senang melihat eiffel di alam liar.
SBI
@ SBI itu hanya kode palsu. :-)
ctrl-alt-delor
Cukup dekat untuk membuatku bahagia;)
SBI