V této části se podíváme na návrhový vzor Strategy. Tento návrhový vzor rozděluje algoritmy na vyšší a nižší části.
Návrhový vzor Strategy se týká toho, že některé algoritmy můžeme rozdělit na vyšší a nižší části. Díky tomu můžeme oddělit funkčnost (vyšší část) od implementace (nižší část) a použít tak algoritmus na více věcí.
Jako příklad rozdělení algoritmu na vyšší a nižší část si můžeme ukázat třeba přípravu čaje. Můžeme ji rozdělit na tuto vyšší a nižší část:
Následující ukázka ukazuje třídu TextProcessor, která slouží k tvorbě listu v různých formátech. Můžeme si vybrat ze dvou formátů: markdown a html. Pro oba tyto formáty jsou v ukázce vytvořeny Strategy třídy, které se starají o nižší část algoritmu pro vytváření listu.
const OutputFormat = Object.freeze({
markdown: 0,
html: 1
});
// základní třída pro List Strategy třídy
class ListStrategy {
start(buffer) {}
konec(buffer) {}
pridejPolozku(buffer, polozka) {}
}
// Strategy pro Markdown List
class MarkdownListStrategy extends ListStrategy {
// ne všechny metody musíme přepsat, pokud je
// nepotřebujeme, tak se budou volat prázdné metody
pridejPolozku(buffer, polozka) {
buffer.push(` * ${polozka}`);
}
}
// Strategy pro HTML List
class HtmlListStrategy extends ListStrategy {
start(buffer) {
buffer.push('<ul>');
}
konec(buffer) {
buffer.push('</ul>');
}
pridejPolozku(buffer, polozka) {
buffer.push(` <li>${polozka}</li>`);
}
}
class TextProcessor {
constructor(outputFormat) {
this.buffer = [];
this.nastavOutputFormat(outputFormat);
}
// pomocí této metody můžeme změnit Strategy
nastavOutputFormat(format) {
switch (format) {
case OutputFormat.markdown:
this.listStrategy = new MarkdownListStrategy();
break;
case OutputFormat.html:
this.listStrategy = new HtmlListStrategy();
break;
}
}
// metoda pro připojení předaného listu položek
pripojList(polozky) {
// v algoritmu se používá nastavená Strategy
this.listStrategy.start(this.buffer);
for (let polozka of polozky)
this.listStrategy.pridejPolozku(this.buffer, polozka);
this.listStrategy.konec(this.buffer);
}
smaz() {
this.buffer = [];
}
toString() {
return this.buffer.join('\n');
}
}
const tp = new TextProcessor(OutputFormat.markdown);
tp.pripojList(['creational', 'structural', 'behavioral']);
console.log(tp.toString());
// vypíše:
// * creational
// * structural
// * behavioral
tp.smaz();
// nastavení jiné Strategy
tp.nastavOutputFormat(OutputFormat.html);
tp.pripojList(['Návrhové', 'Vzory', 'V', 'JS']);
console.log(tp.toString());
// vypíše:
// <ul>
// <li>Návrhové</li>
// <li>Vzory</li>
// <li>V</li>
// <li>JS</li>
// </ul>