JavaScript tervezési minták: a megfigyelő Minta

a JavaScriptben gyakran felmerül egy probléma. Szüksége van egy módra az oldal egyes részeinek frissítésére bizonyos eseményekre adott válaszként, az ezek által megadott adatokkal. Mondja el például a felhasználói bevitelt, amelyet ezután egy vagy több összetevőbe vetít. Ez sok push-and-pull-hoz vezet a kódban, hogy minden szinkronban maradjon.

itt segíthet a megfigyelő tervezési mintája — lehetővé teszi az elemek közötti egy-a-sokhoz adatkötést. Ez az egyirányú adatkötés eseményvezérelt lehet. Ezzel a mintával újrafelhasználható kódot készíthet, amely megoldja az Ön egyedi igényeit.

ebben a cikkben szeretném feltárni az observer tervezési mintáját. Ez segít megoldani egy gyakori probléma látod kliens oldali script. Ez egy a sokhoz, egyirányú és eseményvezérelt adatkötés. Ez egy olyan probléma, amely gyakran felmerül, ha sok eleme van, amelyeknek szinkronban kell lenniük.

az ECMAScript 6-ot fogom használni a minta illusztrálására. Igen, lesznek osztályok, nyíl függvények és állandók. Nyugodtan fedezze fel ezeket a témákat egyedül, ha még nem ismeri. Az ES6 olyan részeit fogom használni, amelyek csak szintaktikai cukrot vezetnek be, tehát szükség esetén hordozható az ES5-Tel.

és a Tesztvezérelt fejlesztést (TDD) fogom használni a minta kidolgozásához. Így van módja annak, hogy megtudja, hogyan hasznos az egyes összetevők.

az új nyelvi funkciók ES6, hogy néhány tömör kódot. Szóval, kezdjük el.

az Eseménymegfigyelő

a minta Magas szintű nézete így néz ki:

EventObserver│ ├── subscribe: adds new observable events│ ├── unsubscribe: removes observable events|└── broadcast: executes all events with bound data

miután kitöltöttem a megfigyelő mintát, hozzáadok egy szót, amely azt használja. A word count komponens fogja ezt a megfigyelőt, és összehozza az egészet.

a EventObserver do inicializálása:

class EventObserver { constructor() { this.observers = ; }}

Kezdje a megfigyelt események üres listájával, és tegye ezt minden új példány esetében. Mostantól adjunk hozzá további módszereket a EventObserver belsejében a tervezési minta részletezéséhez.

a feliratkozási módszer

új események hozzáadásához:

subscribe(fn) { this.observers.push(fn);}

fogd meg a megfigyelt események listáját, és nyomj egy új elemet a tömbbe. Az események listája a visszahívási funkciók listája.

a módszer egyszerű JavaScript-ben történő tesztelésének egyik módja a következő:

// Arrangeconst observer = new EventObserver();const fn = () => {};// Actobserver.subscribe(fn);// Assertassert.strictEqual(observer.observers.length, 1);

csomópont-állításokat használok ennek az összetevőnek a tesztelésére a csomópontban. Pontosan ugyanazok az állítások léteznek, mint a Chai állítások is.

megjegyzés a megfigyelt események listája szerény visszahívásokból áll. Ezután ellenőrizzük a lista hosszát, és kijelentjük, hogy a visszahívás szerepel a listán.

a leiratkozási módszer

az események eltávolításához:

unsubscribe(fn) { this.observers = this.observers.filter((subscriber) => subscriber !== fn);}

szűrje ki a listából, ami megfelel a visszahívási funkciónak. Ha nincs egyezés, a visszahívás a listán marad. A szűrő egy új listát ad vissza, majd újra hozzárendeli a megfigyelők listáját.

ennek a szép módszernek a teszteléséhez tegye meg:

// Arrangeconst observer = new EventObserver();const fn = () => {};observer.subscribe(fn);// Actobserver.unsubscribe(fn);// Assertassert.strictEqual(observer.observers.length, 0);

a visszahívásnak meg kell egyeznie a listán szereplő funkcióval. Ha van egyezés, a leiratkozási módszer eltávolítja azt a listáról. Megjegyzés: a teszt a reference függvényt használja annak hozzáadásához és eltávolításához.

a Broadcast módszer

hívja az összes esemény nem:

broadcast(data) { this.observers.forEach((subscriber) => subscriber(data));}

ez végigmegy a megfigyelt események listáján, és végrehajtja az összes visszahívást. Ezzel megkapja a szükséges egy-sok kapcsolatot az előfizetett eseményekkel. Adja át a data paramétert, amely a visszahívási adatokat köti.

az ES6 nyíl funkcióval hatékonyabbá teszi a kódot. Vegye figyelembe a (subscriber) => subscriber(data) funkciót, amely a legtöbb munkát elvégzi. Ez egysoros nyíl funkció előnyeit ez a rövid ES6 szintaxis. Ez egy határozott javulás a JavaScript programozási nyelvben.

a sugárzási módszer teszteléséhez tegye a következőket:

// Arrangeconst observer = new EventObserver();let subscriberHasBeenCalled = false;const fn = (data) => subscriberHasBeenCalled = data;observer.subscribe(fn);// Actobserver.broadcast(true);// Assertassert(subscriberHasBeenCalled);

használja a let értéket a const helyett, így megváltoztathatjuk a változó értékét. Ez változtathatóvá teszi a változót, amely lehetővé teszi számomra, hogy újra hozzárendeljem értékét a visszahíváson belül. A let kód használata jelet küld a többi programozónak, hogy a változó valamikor megváltozik. Ez növeli a JavaScript kód olvashatóságát és egyértelműségét.

ez a teszt megadja nekem a szükséges bizalmat ahhoz, hogy a megfigyelő úgy működjön, ahogy elvárom. A TDD, ez az egész épület újrafelhasználható kódot sima JavaScript. A tesztelhető kód egyszerű JavaScript-ben történő írásának előnyei vannak. Teszteljen mindent, és tartsa meg azt, ami jó a kód újrafelhasználásához.

ezzel kiegészítettük a EventObserver – et. A kérdés az, hogy mit lehet építeni ezzel?

The Observer Pattern in Action: A Blog Word Count Demo

a demo, ideje, hogy hozzanak létre egy blogbejegyzést, ahol tartja a szavak száma az Ön számára. Minden billentyűleütés, amelyet bemenetként ad meg, szinkronizálódik a megfigyelő tervezési mintájával. Gondolj rá, mint szabad szövegbevitel, ahol minden esemény lő egy frissítést, ahol szükség van rá, hogy menjen.

ahhoz, hogy a szavak száma a szabad szövegbevitel, lehet csinálni:

const getWordCount = (text) => text ? text.trim().split(/\s+/).length : 0;

Kész! Sok minden történik ebben a látszólag egyszerű tiszta funkcióban, Szóval mit szólnál egy szerény egységteszthez? Így egyértelmű, hogy mit szándékoztam ezt tenni:

// Arrangeconst blogPost = 'This is a blog \n\n post with a word count. ';// Actconst count = getWordCount(blogPost);// Assertassert.strictEqual(count, 9);

vegye figyelembe a kissé szokatlan bemeneti karakterláncot a blogPost belsejében. Azt kívánom, hogy ez a funkció a lehető legtöbb edge esetet lefedje. Amíg ez ad nekem egy megfelelő szavak száma haladunk, sőt, a helyes irányba.

mellékesen megjegyezve, ez a TDD valódi ereje. Ezt a megvalósítást meg lehet ismételni, és a lehető legtöbb felhasználási esetet lefedni. Az egység teszt megmutatja, hogyan várom el, hogy viselkedjen. Ha a viselkedésnek bármilyen okból hibája van, könnyen megismételhető és módosítható. A teszttel elegendő bizonyíték marad hátra ahhoz, hogy bármely más személy változtatásokat hajtson végre.

ideje bekötni ezeket az újrafelhasználható alkatrészeket a DOM-ba. Ez az a rész, ahol kapsz forgatni sima JavaScript és hegeszteni egyenesen a böngésző.

ennek egyik módja az lenne, ha a következő HTML lenne az oldalon:

<textarea placeholder="Enter your blog post..." class="blogPost"></textarea>

ezt követi ez a JavaScript:

const wordCountElement = document.createElement('p');wordCountElement.className = 'wordCount';wordCountElement.innerHTML = 'Word Count: <strong>0</strong>';document.body.appendChild(wordCountElement);const blogObserver = new EventObserver();blogObserver.subscribe((text) => { const blogCount = document.getElementById('blogWordCount'); blogCount.textContent = getWordCount(text);});const blogPost = document.getElementById('blogPost');blogPost.addEventListener('keyup', () => blogObserver.broadcast(blogPost.value));

vegye ki az összes újrafelhasználható kódot, és helyezze be az observer tervezési mintát. Ez nyomon követi a szövegterület változásait, és egy szószámot ad közvetlenül alatta. A body.appendChild() – et használom a DOM API-ban az új elem hozzáadásához. Ezután csatolja az esemény hallgatóit, hogy életre keltsék.

megjegyzés a nyílfunkciókkal lehetőség van egysoros események bekötésére. Valójában ezzel eseményvezérelt változásokat közvetít az összes előfizető számára. A () => blogObserver.broadcast() itt végzi a munka nagy részét. Még a szövegterület legújabb módosításaiban is közvetlenül a visszahívási funkcióba kerül. Igen, az ügyféloldali szkriptek nagyon klasszak.

egyetlen bemutató sem teljes anélkül, hogy megérintené és csípné, az alábbiakban a kódlap található:

lásd a Pen The Observer mintát a SitePoint (@SitePoint) alapján a CodePen-en.

most nem nevezném ezt a funkciót teljesnek. Ez csak a megfigyelő tervezési mintájának kiindulópontja. A kérdés az, meddig vagy hajlandó elmenni?

előretekintve

az Ön feladata, hogy ezt az ötletet még tovább vigye. Számos módon használhatja a megfigyelő tervezési mintát új funkciók felépítéséhez.

akkor fokozza a demo:

  • egy másik összetevő, amely megszámolja a bekezdések számát
  • egy másik összetevő, amely a beírt szöveg előnézetét mutatja
  • fokozza az előnézetet a markdown Támogatással, például

ez csak néhány ötlet, amellyel mélyebbre süllyedhet. A fenti fejlesztések kihívást jelentenek a programozási szeletekre.

következtetés

az observer tervezési minta segíthet megoldani a valós problémákat a JavaScript-ben. Ez megoldja azt az évelő problémát, hogy egy csomó elemet szinkronizálnak ugyanazokkal az adatokkal. Mint gyakran, amikor a böngésző konkrét eseményeket indít. Biztos vagyok benne, hogy a legtöbben már találkoztak egy ilyen problémával, és az eszközök és a harmadik féltől származó függőségek felé futottak.

ez a tervezési minta felvértezi, hogy menjen, amennyire a képzelet hajlandó menni. A programozás során elvontuk a megoldást egy mintába, és újrafelhasználható kódot építünk. Nincs korlátozva, hogy ez milyen messzire visz.

remélem, látja, hogy egy kis fegyelemmel és erőfeszítéssel mennyit tehet egyszerű JavaScriptben. A nyelv új funkciói, például az ES6, segítenek néhány tömör, újrafelhasználható kód megírásában.

ezt a cikket Giulio Mainardi szakértői véleményezte. Köszönet a SitePoint összes szakértői véleményezőjének, hogy a SitePoint tartalmát a lehető legjobbá tették!

Vélemény, hozzászólás?

Az e-mail-címet nem tesszük közzé.