Де ми ставимо код «запитуючи світ», коли ми розмежовуємо обчислення від побічних ефектів?


10

Відповідно до принципу розділення команд-запитів , а також мислення в даних і DDD з презентаціями Clojure слід відокремлювати побічні ефекти (модифікуючи світ) від обчислень та рішень, щоб було легше зрозуміти і перевірити обидві частини.

Це залишає без відповіді питання: де відносно кордону слід поставити "запитання світу"? З одного боку, запит даних із зовнішніх систем (наприклад, бази даних, API служб розширення тощо) не є референтно прозорим і, таким чином, не повинен сидіти разом з чистим кодом для обчислень та прийняття рішень. З іншого боку, проблематично або, можливо, неможливо розірвати їх окремо від обчислювальної частини і передавати це як аргумент, тому що ми можемо не знати заздалегідь, які дані нам можуть знадобитися запитувати.


1
Ось тут і з'являються поняття зворотного виклику. Якщо ви не знаєте заздалегідь, які дані можуть знадобитися, надайте зворотний виклик обчислювальному коду, де він може вказати, які дані йому потрібні, а інші шари виконають фактичне отримання та надання . Якщо він повинен бути асинхронним, зворотний виклик навіть може вказати іншу функцію для виклику зі зібраними даними, коли вони стануть доступними.
Мар'ян Венема

1
@MarjanVenema, це єдиний варіант, який мені також спадає на думку. Просто з теоретичної точки зору: якщо метод, інакше без побічних ефектів, викликає побічний зворотний виклик, він стає побічним. Можливо, моя проблема тут полягає в тому, що я припускаю, що обчислення розділення від побічних ефектів вимагає, щоб обчислення були референційно прозорими. Хоча це не обов'язково правда.
Олексій

1
Якщо це турбує вас, ваші обчислення просто недостатньо чіткі. Вам потрібно абстрагувати прийняття рішення щодо того, які інші дані / кроки потрібні. Тому розділіть повне обчислення на кроки, залежно від того, де приймаються рішення щодо необхідних даних. Тоді є якийсь "директор", який керує робочим процесом для повного обчислення: починаючи кожен крок, повертаючи інформацію з кожного кроку, використовуючи для того, щоб визначити наступний крок і потрібні дані, запустивши процес отримання і отримати його, а потім передати отримані дані до наступного кроку обчислення.
Мар'ян Венема

Відповіді:


1

З іншого боку, проблематично або, можливо, неможливо розірвати їх окремо від обчислювальної частини та передавати це як аргумент, тому що ми можемо не знати заздалегідь, які дані нам можуть знадобитися запитувати.

Це випадок, коли, як зазначається в коментарях, передача здатності витягувати дані (наприклад, функція першого класу, об'єкт, що реалізує інтерфейс тощо) забезпечує зручний механізм виділення побічних ефектів.

Функція вищого порядку, чисте тіло має нефіксовану чистоту: http://books.google.com/books?id=Yb8azEfnDYgC&pg=PA143#v=onepage&q&f=false

Я писав про це, називаючи цей тип функції потенційно чистою функцією: http://adamjonrichardson.com/2014/01/13/potential-pure-functions/

Якщо поєднувати потенційно чисту функцію з функціями, що пропускаються (у яких бракує розгалужувальних конструкцій і виконуються якнайменше), комбінацію, яку я називаю наборами ізоляції, можна досить ефективно виділити побічні ефекти та створити дуже перевірений код: http: // adamjonrichardson.com/2014/01/15/isolating-side-effects-using-isolation-sets/


0

Ви зберігаєте результат у класі, це спочатку здається дещо дивним, але призводить до спрощення коду. наприклад, немає тимчасових змінних у виклику.

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
Люблю бачити Ейфелеву в дикій природі.
СБІ

@sbi це просто псевдо-код. :-)
ctrl-alt-delor

Досить близько, щоб зробити мене щасливим;)
SBI
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.