Работы по библиотеке Patron вдохновлены двумя книгами: Elegant Objects и Object Thinking
В этом разделе сделаем пример кода по расчету простой арифметической формулы с возможностью изменять переменные и одна из переменных будет таймером.
Результат 1. Вычисление на лету
Листинг 1.
import {
Guest,
Source,
Patron,
SourceAll,
GuestCast,
GuestDisposable,
} from "patron-oop";
import { Text, Input } from "patron-components";
// Переместил клиентский код наверх,
// чтобы не крутить до самой интересной части.
window.numberTimer = new NumberFromTimer();
const numberInput1 = new NumberFromInput(".input-1");
const numberInput2 = new NumberFromInput(".input-2");
const result = new Multiplication(
new Addition(numberInput1, numberTimer),
numberInput2
);
numberTimer.start();
numberTimer.number(
new Patron(
new GuestDisposable(
new Text(".eo-counter"),
disposeIfNoSelector(".eo-counter")
)
)
);
result.number(
new Patron(
new GuestDisposable(
new Text(".eo-result"),
disposeIfNoSelector(".eo-result")
)
)
);
class NumberFromTimer {
timerHead = null;
constructor() {
this.source = new Source(1);
}
number(guest) {
this.source.value(guest);
}
start() {
if (this.timerHead) {
return;
}
const repeat = () => {
this.source.value((value) => {
this.timerHead = setTimeout(() => {
this.source.give(value + 1);
repeat();
if (!this.source.pool().size()) {
this.stop();
}
}, 1000);
});
};
repeat();
}
stop() {
clearTimeout(this.timerHead);
this.timerHead = null;
}
reset() {
this.stop();
this.source.give(1);
this.start();
}
}
class NumberFromInput {
constructor(selector) {
this.source = new Source(1);
this.input = new Input(this.source, selector);
}
number(guest) {
this.source.value(
new GuestCast(guest, (value) => {
guest.give(+value);
})
);
}
}
class Addition {
constructor(num1, num2) {
this.num1 = num1;
this.num2 = num2;
}
number(guest) {
const all = new SourceAll();
this.num1.number(new GuestCast(guest, all.guestKey("n1")));
this.num2.number(new GuestCast(guest, all.guestKey("n2")));
all.value(
new GuestCast(guest, ({ n1, n2 }) => {
guest.give(n1 + n2);
})
);
}
}
class Multiplication {
constructor(num1, num2) {
this.num1 = num1;
this.num2 = num2;
}
number(guest) {
const all = new SourceAll();
this.num1.number(new GuestCast(guest, all.guestKey("n1")));
this.num2.number(new GuestCast(guest, all.guestKey("n2")));
all.value(
new GuestCast(guest, ({ n1, n2 }) => {
guest.give(n1 * n2);
})
);
}
}
const disposeIfNoSelector = (selector) => () =>
!document.querySelector(selector);