V této části se podíváme na návrhový vzor Bridge. Tento návrhový vzor můžeme použít k propojení různých komponent.
Bridge spočívá v tom, že při vytváření objektu mu jako vlastnost nastavíme jiný objekt. Objekt tedy bude mít k objektu spojení (odtud název Bridge - Most) a může s ním pracovat.
Díky návrhovému vzoru Bridge nemusíme přidávat funkcionalitu pomocí dědění tříd, ale můžeme třídě jako vlastnost předávat nějaký objekt, který požadovanou funkcionalitu poskytuje.
Představme si, že vytváříme nějakou aplikaci, ve které se vykreslují různé geometrické objekty. V této aplikaci chceme objekty vykreslovat dvěma odlišnými způsoby: rastrově a vektorově. Následující ukázka ukazuje, jak bychom mohli vykreslování objektů oběma způsoby umožnit. V ukázce se nachází třída Kruh od které dědí třídy RasterKruh a VectorKruh. Třída RasterKruh slouží pro reprezentaci a vykreslování kruhu rastrovaně a třída VectorKruh vektrově.
class Kruh {
constructor(x, y, polomer) {
this.x = x;
this.y = y;
this.polomer = polomer;
}
}
// třída pro kruh, který se má vykreslovat rastrovaně
class RasterKruh extends Kruh {
constructor(x, y, polomer) {
super(x, y, polomer);
}
// metoda pro vykreslení kruhu rastrovaně
vykresli() {
console.log(`Vykresluji RASTROVĚ kruh s poloměrem ${this.polomer}` +
` na souřadnicích [${this.x}, ${this.y}].`);
}
}
// třída pro kruh, který se má vykreslovat vektorově
class VektorKruh extends Kruh {
constructor(x, y, polomer) {
super(x, y, polomer);
}
// metoda pro vykreslení kruhu vektorově
vykresli() {
console.log(`Vykresluji VEKTOROVĚ kruh s poloměrem ${this.polomer}` +
` na souřadnicích [${this.x}, ${this.y}].`);
}
}
const kruh = new RasterKruh(5, 8, 14);
kruh.vykresli();
Pokud nechceme pro každý objekt, který v aplikaci vykreslujeme, vytvářet třídu pro jeho vykreslování rastrovaně a vektorově, tak si pro vykreslování můžeme vytvořit speciální komponentu. Následující ukázka ukazuje třídu RasterRenderer, která slouží pro vykreslování objektů rastrovaně a třídu VectorRenderer, která slouží k vektorovému vykreslování objektů. Namísto dvou tříd pro každý objekt tedy máme jen jednu a při vytváření její instance jen předáváme, který renderer chceme pro vykreslování použít.
// renderer pro rastrové vykreslování objektů
class RasterRenderer {
vykresliKruh(x, y, polomer) {
console.log(`Vykresluji RASTROVĚ kruh s poloměrem ${polomer}` +
` na souřadnicích [${x}, ${y}].`);
}
}
// renderer pro vektorové vykreslování objektů
class VectorRenderer {
vykresliKruh(x, y, polomer) {
console.log(`Vykresluji VEKTOROVĚ kruh s poloměrem ${polomer}` +
` na souřadnicích [${x}, ${y}].`);
}
}
// základní třída pro všechny tvary, které se v aplikaci vykreslují
class Tvar {
// zde vlastně Bridge probíhá
// - odkaz na renderer se uloží jako vlastnost objektu
constructor(renderer) {
this.renderer = renderer;
}
}
class Kruh extends Tvar {
constructor(renderer, x, y, polomer) {
super(renderer);
this.x = x;
this.y = y;
this.polomer = polomer;
}
vykresli() {
// o vykreslení kruhu se postará nastavený renderer
this.renderer.vykresliKruh(this.x, this.y, this.polomer);
}
}
const renderer = new RasterRenderer();
// při vytváření objektu se předává renderer, který se má použít pro vykreslování
const kruh = new Kruh(renderer, 5, 8, 14);
kruh.vykresli();