Kako stvoriti trgovinu pomoću čistih funkcija

Discover Functional JavaScript proglašen je jednom od najboljih novih knjiga o funkcionalnom programiranju od strane BookAuthority!

Fotografiju Ugur Akdemir na Unsplash

Čiste funkcije proizvode istu izlaznu vrijednost s istim ulazom. Nemaju nuspojava te ih je lakše čitati, razumjeti i testirati.

S obzirom na sve to, želio bih stvoriti trgovinu koja skriva stanje, ali istovremeno koristi čiste funkcije.

Nepromjenljivost

Čiste funkcije ne mijenjaju svoj unos. Ulazne vrijednosti tretiraju kao nepromjenjive.

Nepromjenjiva vrijednost je vrijednost koju, jednom stvorena, ne može promijeniti.

Immutable.js pruža nepromjenjive strukture podataka poput Popisa. Nepromjenjiva struktura podataka stvorit će novu strukturu podataka pri svakoj radnji.

Razmotrite sljedeći kod:

import {List} iz "nepromjenjivog";
const list = Lista ();
const newList = list.push (1);

push () stvara novi popis koji sadrži novi element. To ne mijenja postojeći popis.

delete () vraća novi Popis s kojeg je uklonjen element navedenog indeksa.

Struktura podataka Popisa nudi lijepo sučelje za rad s popisima na nepromjenjiv način, pa ću ga koristiti kao vrijednost države.

Dućan

Trgovina upravlja državom.

Država su podaci koji se mogu promijeniti. Trgovina skriva te državne podatke i nudi javni skup metoda za rad s njima.

Želio bih stvoriti trgovinu knjiga metodama add (), remove () i getBy ().

Želim da sve ove funkcije budu čiste funkcije.

Postoje dvije vrste čistih funkcija koje trgovina koristi:

  • funkcije koje će čitati i filtrirati stanje. Nazvat ću ih getterima.
  • funkcije koje će modificirati stanje. Nazvat ću ih seterima.

Obje ove funkcije će stanje uzeti kao svoj prvi parametar.

Pišimo u trgovinu pomoću čistih funkcija.

import {List} iz "nepromjenjivog";
uvoz djelomičan iz "lodash / djelomičan";
uvozi podudaranjaProvrednost iz "lodash / matchProperty";
// utemeljitelji
dodavanje funkcije (knjige, knjiga) {
  vratiti knjige.push (knjiga);
}
funkcija ukloniti (knjige, knjiga) {
  const index = books.findIndex (matchProperty ("id", book.id));
  povrat knjige.delete (indeks);
}
// getters
funkcija upitaContainsBook (upit, knjiga) {
  ako (upit && query.text) {
    return book.title.includes (query.text);
  }
  povratak istinit;
}
funkcija getBy (knjige, upit) {
  vratiti books.filter (djelomičan (queryContainsBook, query)). toArray ();
}

Knjižnica

Stanje treba sakriti unutar objekta trgovine. Ne želim slati stanje izvana u objekt trgovine. Istodobno, želim dobiti sve prednosti čistih funkcija i upotrijebiti ih za definiranje metoda pohrane.

Kako se to može postići?

Odgovor smo vidjeli u Reduxu. Pišemo čiste funkcije i dopuštamo knjižnici da stvori trgovinu i primijenimo čiste funkcije.

Evo kako bih želio pomoću knjižnice definirati trgovinu:

import {List} iz "nepromjenjivog";
import Store iz "./Store-toolbox";
// utemeljitelji
dodavanje funkcije (knjige, knjiga) {}
uklanjanje funkcije (knjige, knjiga) {}
// getters
funkcija getBy (knjige, upit) {}
izvoz zadane trgovine ({
  stanje: Popis (),
  postave: {dodaj, ukloni},
  getters: {getBy}
});

Izgradimo tu mikro-biblioteku koja će prodavaonicu stvoriti na temelju čistih proizvođača i settera.

Svi javni skupljači i setteri bit će ukrašeni i primit će stanje kao njihov prvi parametar.

  • Povratna vrijednost s poslužitelja vraća se funkcijama pozivatelja.
  • Vraćena vrijednost stetera koristi se za promjenu stanja. Funkcije pozivatelja neće primiti novo stanje.
funkcija decoMethods (obj, stolisnik) {
  neka newObject = {... obj};
  Object.keys (newObject) .forEach (funkcija decoMethod (fnName) {
    if (upišite newObject [fnName] === "funkcija") {
      newObject [fnName] = dekorater (newObject [fnName]);
    }
  });
  vratiti noviObject;
}
funkcija Store (storeConfig) {
  povratna funkcija () {
    neka država = storeConfig.state;
    funkcija za postavljanje (fn) {
      funkcija povratka (... args) {
        stanje = fn (država, ... args);
      };
    }
    funkcija getter (fn) {
      funkcija povratka (... args) {
        return fn (država, ... args);
      };
    }
    vratiti Object.freeze ({
      ... decoMethods (storeConfig.getters, getter),
      ... decoMethods (storeConfig.setters, setter)
    });
  };
}
izvoz zadane trgovine;

Store () stvara funkciju koja vraća objekt koji enkapsulira stanje.

Stvorimo i koristimo BookStore objekt:

uvesti BookStore iz "./BookStore";
const bookStore = BookStore ();
bookStore.add ({id: 1, naslov: "Kako funkcionira JavaScript"});

Kada poziva bookStore.add ({}), uređivač postavljanja će pozvati funkciju add () pure setter s trenutnim stanjem kao prvim parametrom i novu knjigu kao drugim parametrom. Zatim će uređivač seta upotrijebiti rezultat za promjenu vrijednosti stanja.

Predmet

Analiziramo objekt BookStore.

Izlaže samo tri metode, a sve ostale čiste funkcije su privatne.

Javno sučelje objekta se ne može mijenjati izvana.

Država je skrivena. Klijenti koji koriste objekt bookStore mogu pristupiti državi samo javnim metodama.

Zaključak

Čiste funkcije su lakše razmisliti.

Pomoću biblioteke možemo stvoriti trgovinu koja skriva stanje i koristi čiste funkcije.

Mi možemo pisati samo čiste funkcije i dopustiti knjižnici da ih primjenjuje te izvršiti mutaciju.

Primjer koda možete provjeriti na codeandbox.io.

Discover Functional JavaScript proglašen je jednom od najboljih novih knjiga o funkcionalnom programiranju od strane BookAuthority!

Više o primjeni funkcionalnih tehnika u Reactu pogledajte u funkcionalnoj reakciji.

Naučite kako primijeniti principe dizajna uzoraka.

Možete me naći na Twitteru.