@zlodiak

В чём отличие functional reactive и imperative ractive подходов?

В одной книжке нашёл два примера реактивного подхода. Но не понимаю в чём их принципиальное отличие. Помогите пожалуйста разобраться.

Императивный реактивный подход. Живое демо здесь
Код:
class Calculator {
  constructor(){
    this.VAT = 22;
  }
  sum(items){
    const items$ = Rx.Observable.from(items);
    const total$ = items$.map(value => value + (value * this.VAT/100))
    .reduce((acc, value) => acc + value);
    return total$;
  }
}

class Receipt {
  constructor(calculator){
    this.calc = calculator;
  }
  print(...items){
    const total$ = this.calc.sum(items);
    total$.subscribe(total => console.log(`total receipt £${total.
toFixed(2)}`));
  }
}


const JEANS = 80.00;
const SHIRT = 35.00;
const SHOES = 90.00;
const COAT = 140.00;
const HAT = 29.00;

const calc = new Calculator();
const receipt = new Receipt(calc);

receipt.print(JEANS, SHIRT, SHOES, COAT, HAT);


Функциональный реактивный подход. Живое демо здесь.
Код:
class Calculator {
  getTotal(...items){
    const items$ = Rx.Observable.from(items);
    const total$ = items$.map(v => this.addVAT(v))
                     .reduce(this.sumElements);
    return total$;
  }
  addVAT(itemValue){
    return itemValue + this.calculateVAT(itemValue);
  }
  calculateVAT(value){
    const VAT = 22;
    return value * VAT/100;
  }
  sumElements(accumulator, value){
    return accumulator + value
  }
}

class Receipt {
  print(total$){
    total$.subscribe(total => console.log(`total receipt £${total.
toFixed(2)}`));
  }
}


const JEANS = 80.00;
const SHIRT = 35.00;
const SHOES = 90.00;
const COAT = 140.00;
const HAT = 29.00;

const calc = new Calculator();
const receipt = new Receipt();

receipt.print(calc.getTotal(JEANS, SHIRT, SHOES, COAT, HAT));


На мой взгляд в обоих примерах отсутствуют внешние переменные, в которых хранится промежуточное состояние. Поэтому я бы оба эти примера отнёс к функциональному программированию. Но автор книги со мной не согласился бы.
  • Вопрос задан
  • 254 просмотра
Решения вопроса 1
Tyranron
@Tyranron
В первом примере (императивном), у Вас объект класса Calculator после создания хранит в себе состояние: this.VAT = 22. И все последующие методы этого класса работают с этим состоянием (контекстом класса).

Во втором же примере (функциональном) - напротив, никакого состояния у класса нет. Он, по сути, являет собой отдельный неймспейс для чистых функций. Функции в своей работе абсолютно не затрагивают состояние объекта.

Вообще, ИМХО, пример просто плохой. Добавьте в оба примера логику мутации (изменения) VAT, и Вам сразу же станет понятно в чём различие. Ибо в первом примере Вы будете напрямую изменять this.VAT, и использовать его потом. А во втором примере, Вам придётся прокидывать значение VAT параметром, нигде его не храня.

А отличие functional reactive и imperative reactive подходов в том, что:

1. В функциональном подходе Вся ваша программа - это, по сути, одна большая чистая функция, составленная из композиции многих маленьких (как формула в математике), и по которой данные, по сути, текут, преобразовываясь в нужный результат на выходе.

2. В императивном же подходе у Вас данные размазаны по отдельным живущим сущностям, у которых есть своё внутреннее состояние, и которые общаются между собой. Реактивность тут только в том, что у этих сущностей свойства реактивные, то есть при изменении свойства, все зависящие от него сущности перевычисляют зависящие свойства/значения.

Разница, как таковая, не в реактивности, а всего лишь в способе декомпозиции задачи. Реактивность что там, что сям, по сути одна и та же (в примере: Rx.Observable.from(items)).
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
rockon404
@rockon404
Frontend Developer
Императивное программирование описывает логику работы программы в явных командах с операторами, изменяющими состояние программы.
Функциональное программирование описывает логику работы программы, как вычисление значений функций и не предполагает явного хранения состояния программы.

Императивный стиль:
const result = 10 * 10 + 15 * 2;
console.log(result);

Функциональный стиль:
console.log(sum(square(10), double(15)));
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
18 апр. 2024, в 21:56
2000 руб./за проект
18 апр. 2024, в 21:00
150 руб./за проект