V této části se podíváme na Object Pool. Tento návrhový vzor slouží k uchovávání použitých objektů, abychom je v budoucnu mohli znovu použít a nemuseli vytvářet nové instance. Object Pool nepatří mezi Gang of Four návrhové vzory, ale rozhodně jsem jej na těchto webových stránkách chtěl mít. Používal jsem jej totiž ještě předtím, než jsem se návrhové vzory začal učit a můžu říct, že dokáže být hodně užitečný.
Návrhový vzor Object Pool můžeme použít, když opakovaně vytváříme instance nějaké třídy a tyto instance jsou v našem programu jen určitou dobu. Tvorba objektu může být náročná a může nám zpomalovat program. Proto si můžeme použité objekty někde ukládat, a když budeme potřebovat nový objekt, tak si namísto vytváření nové instance jen vezmeme objekt, který jsme již v minulosti použili.
Object Pool slouží k vytváření a uchovávání instancí nějaké třídy. Když potřebujeme novou instanci, tak řekneme Object Poolu aby nám ji dal, a když už ji nebudeme potřebovat, tak ji Object Poolu vrátíme. Object Pool nám dává buď nové instance, když zrovna nemá žádné k dispozici, nebo inicializuje již použité.
Následující ukázka Object Pool ukazuje, představuje jej třída ObjectPool. Při vytváření Object Poolu si určujeme, jaké instance třídy bude Object Pool uchovávat. V našem příkladu si vytváříme Object Pool pro objekty třídy Strela. Object Pool obsahuje metody ziskat a vratit. Metodu ziskat můžeme použít k získání objektu a metodu vratit můžeme použít k vrácení objektu, když už jej nepotřebujeme.
class ObjectPool {
constructor(konstruktor) {
// uložení konstruktoru pro vytvoření nového objektu
this._konstruktor = konstruktor;
// v tomto poli se budou uchovávat použité objekty
this._objekty = [];
}
// metoda k získání objektu z Object Poolu
ziskat() {
// pokud Object Pool neobsahuje žádné použité objekty, tak se vytvoří nový objekt
if (this._objekty.length === 0) return new this._konstruktor();
// získání objektu z pole obsahující použité objekty
const objekt = this._objekty.pop();
// inicializace objektu
objekt.init();
return objekt;
}
// metoda pro vrácení použitého objektu zpět do Object Poolu
vratit(objekt) {
// zresetování objektu
objekt.reset();
// uchování objektu pro znovupoužití
this._objekty.push(objekt);
}
}
class Strela {
constructor() {
this.init();
this.pouzita = false;
}
// tato metoda je volána Object Poolem
// pro inicializaci použitého objektu
init() {
this.x = 0;
this.x = 0;
}
// tato metoda je volána Object Poolem
// při vrácení použitého objektu
reset() {
// toto by se dalo dělat i v init metodě, metoda reset slouží hlavně
// k tomu, aby se třeba vyprázdnilo nějaké pole, které objekt obsahuje
// a uvolnila se tak paměť již při vrácení objektu do Object Poolu
this.pouzita = false;
}
pouzit(x, y) {
if (this.pouzita) return;
console.log("něco se provede...")
this.x = x;
this.y = y;
this.pouzita = true;
}
}
// vytvoření Object Poolu pro třídu Strela
const objectPool = new ObjectPool(Strela);
// získání objektu z Object Poolu
const strela = objectPool.ziskat();
strela.pouzit();
// vrácení objektu do Object Poolu
objectPool.vratit(strela);
// získání objektu z Object Poolu
const strela2 = objectPool.ziskat();
strela2.pouzit();