všetky vzory

Object Pool

Požičiava drahé objekty zo zásoby a po použití ich berie späť.

class Spojenie {  vykonaj(dopyt) {    // práca nad drahým zdrojom  }} class SpojeniaPool {  #volne = [];  #pozicane = new Set();   constructor(pocet) {    for (let i = 0; i < pocet; i += 1) {      this.#volne.push(new Spojenie());    }  }   ziskaj() {    if (this.#volne.length === 0) {      throw new Error('pool je prázdny');    }    const spojenie = this.#volne.pop();    this.#pozicane.add(spojenie);    return spojenie;  }   vrat(spojenie) {    this.#pozicane.delete(spojenie);    this.#volne.push(spojenie);  }} const pool = new SpojeniaPool(3); const a = pool.ziskaj();const b = pool.ziskaj(); pool.vrat(a);const c = pool.ziskaj(); a === c;   // true — pool vydal ten istý objekt znova

Celý priebeh v texte (11 krokov)
  1. Pool si spojenia vyrobí dopredu, ešte kým o ne niekto požiada. Práve preto vzor existuje: vznik je drahý a má sa zaplatiť raz.
  2. UlohaA si vypýta spojenie. Nepýta si konkrétne — chce ktorékoľvek voľné.
  3. Pool jedno vydá a vyškrtne si ho z voľných. Objekt neputuje ako kópia, odchádza ten istý — v poole po ňom zostalo prázdne miesto.
  4. UlohaB žiada tiež.
  5. Dostane druhé v poradí. Ktoré presne, jej je jedno — objekty sú zameniteľné.
  6. Voľné zostalo jediné. Toto je druhá polovica vzoru: pool vie, koľko ich je vonku, a keď dôjdu, ďalší žiadateľ počká — nové sa nevyrobí.
  7. UlohaA dorobila svoju prácu a spojenie vracia. Nezahadzuje ho — posiela ho späť tam, odkiaľ si ho požičala.
  8. A je späť vo svojom mieste. Tá istá gulička, akú si UlohaA pred chvíľou odniesla — nič nevzniklo a nič nezaniklo.
  9. UlohaA potrebuje spojenie znovu.
  10. A dostane presne tú istú guličku, ktorú predtým vrátila. Druhýkrát sa za jej vytvorenie neplatilo nič.
  11. Tri žiadosti, tri objekty — a všetky tri vznikli na začiatku. Vzor nešetrí na tom, koľko objektov je, ale na tom, koľkokrát vznikajú.

Kedy použiť

  • Objekt je drahý na vytvorenie a lacný na použitie. Spojenie do databázy, vlákno, otvorený soket — zaplatíte raz a potom ho len požičiavate.
  • Zdroj je vyčerpateľný a jeho počet treba držať pod stropom. Pool je jediné miesto, ktoré vie, koľko ich je vonku, a vie ďalšieho žiadateľa nechať čakať.
  • Objekty sú navzájom zameniteľné. Žiadateľovi je jedno, ktorý dostane — keby mu na tom záležalo, potrebuje register podľa kľúča, nie pool.
  • Vytváranie a rušenie prebieha často a v krátkych cykloch. Práve tam sa cena za vznik objektu nasčíta do niečoho, čo je vidieť na výkone.

Pasce

  • Vrátený objekt si nesie starý stav. Toto je najdrahšia pasca vzoru: kto ho dostane ďalší, zdedí rozrobenú transakciu alebo cudzie dáta. Pool musí objekt pri vrátení vyčistiť, inak požičiava tichú chybu.
  • Kto si objekt požičia a nevráti ho, pool vyhladoví. Chýbajúce vrátenie nie je vidieť ako chyba — prejaví sa až o hodinu ako čakanie, ktoré nemá zjavnú príčinu.
  • Objekt použitý po vrátení patrí už niekomu inému. Žiadateľ si naň nesmie nechať odkaz, ale nič mu v tom nebráni — a dvaja potom píšu do toho istého zdroja.
  • Zamieňa sa s Multitonom. Register podľa kľúča drží väzbu trvalo a nikto nič nevracia; pool požičiava čokoľvek voľné a späť to čaká. Keď potrebujete konkrétnu instanciu, pool je zlý nástroj.
  • Pri lacnom objekte je pool pomalší než obyčajné vytvorenie. Réžia požičiavania, vracania a synchronizácie sa neplatí sama — musí ju vyvážiť cena vzniku.
  • Veľkosť poolu je hádanie. Primalý znamená čakanie, priveľký drží zdroje, ktoré nikto nepoužíva — a správne číslo sa mení s prevádzkou, nie s návrhom.
  • Vzor skrýva, že zdroj sa dá vyčerpať. Kód vyzerá, akoby objekt bol vždy k dispozícii, a vyčerpanie sa prejaví až tam, kde ho nikto nečaká.