Odtwarzamy koncepcje pipe z programowania funkcyjnego w programowaniu obiektowym w JavaScript. Do dzieła.

Na początku przypomnienie, jak działa pipe w funkcyjnym paradygmacie:

const addTwo = (num) => num + 2;

const mulByTwo = (num) => num * 2;

const pipe = (...fns) => (data) => fns.reduce((acc, fun) => fun(acc), data);


const piped = pipe(
    addTwo,
    mulByTwo
);


let num = 2;
let pipedResult = piped(num);

console.log(pipedResult);
//8

Tworzymy klasę z prywatnymi polami:

class Pipe {
    #data = null;
    #functions = [];
}

Dodajemy dwie metody, które są chainable (return this). Funkcje dodajemy w takiej kolejności, aby popując je z tablicy pierwsza spadła dodana jako pierwsza:

class Pipe {
    #data = null;
    #functions = [];

    setData(data) {
        this.#data = data;
        return this;
    }

    pipeFunc(func){
        this.#functions = [func, ...this.#functions];
        return this;
    } 
}

Teraz dodajemy logikę metody start:

class Pipe {
    #data = null;
    #functions = [];

    //(...)

    start(){

        if(!this.#data)
            throw new Error("Data empty!");

        while(this.#functions.length){
            let currFunc = this.#functions.pop();
            this.#data = currFunc(this.#data);
        }

        let result = this.#data;
        this.#data = null;
        return result;
    }
}

Testujemy:

const addTwo = (num) => num + 2;

const mulByTwo = (num) => num * 2;

const pipe = (...fns) => (data) => fns.reduce((acc, fun) => fun(acc), data);


const piped = pipe(
    addTwo,
    mulByTwo
);


let num = 2;
let pipedResult = piped(num);

console.log(pipedResult);
//8

let pipe2 = new Pipe();
pipe2.setData(num)
.pipeFunc(addTwo)
.pipeFunc(mulByTwo);

let pipedResult2 = pipe2.start();
console.log(pipedResult2);
//8

pipe2.start();
//Uncaught Error: Data empty!