Фото Родіона Куцайєва на Unsplash
Що таке патерн проектування Template?
Уявіть собі Бетмена (так, того самого — героя в плащі!) і Робіна, які намагаються розкрити злочин. Кожного разу, коли вони вирушають на місію, Бетмен робить своє: розслідує місце злочину, бореться з поганцями і видає кумедні репліки. Робін робить те ж саме, але він ще вивчає, як бути супергероєм. Бетмен має чітку рутину, але він настільки щедрий, що дозволяє Робіну робити це по-своєму. Ось і є Template Design Pattern!
Це як шаблон для низки кроків, які повинні виконуватись, але з можливістю налаштування окремих частин підкласами. Тобто, структура залишається незмінною (тому що злочинці — це завжди злочинці), але деталі (як Бетмен бореться з ними, наприклад) можуть змінюватися.
Режим Бетмена = Шаблон
Бетмен має фіксовану рутину боротьби зі злочинцями, але є місця, де він дозволяє Робіну імпровізувати. Ось розбір його шаблону:
- Виявити злочин — Бетмен завжди спостерігає за Готемом.
- Зустрітися з лиходієм — Жоден злочинець не уникає Бетмена!
- Битися з лиходієм — Бетмен має багато класних рухів.
- Видавати драматичну репліку — Класика Бетмена. «Я — ніч!»
- Зберегти Готем — Зазвичай після цього слідує героїчний вихід.
Тепер поглянемо на шаблон Бетмена:
abstract class Batcave {
// Шаблонний метод - визначає скелет процесу боротьби зі злочинцями
public final void fightCrime() {
detectCrime();
confrontVillain();
fightVillain();
deliverLine();
saveGotham();
}
// Конкретні методи
private void detectCrime() {
System.out.println("Бетмен виявляє злочин у Готемі.");
}
private void confrontVillain() {
System.out.println("Бетмен стикається з лиходієм у тіні.");
}
private void deliverLine() {
System.out.println("Бетмен видає драматичну репліку: 'Я — ніч!'");
}
private void saveGotham() {
System.out.println("Бетмен зберігає Готем. Знову.");
}
// Абстрактний метод - ця частина залишається на розсуд підкласів
protected abstract void fightVillain();
}
class Batman extends Batcave {
// Унікальний спосіб Бетмена боротися з лиходіями
@Override
protected void fightVillain() {
System.out.println("Бетмен використовує гаджети для боротьби з лиходієм. БУМ! ЗАП! ПОУ!");
}
}
class Robin extends Batcave {
// Унікальний (і менш ефективний) спосіб Робіна боротися з лиходіями
@Override
protected void fightVillain() {
System.out.println("Робін намагається боротися з лиходієм, але в основному спотикається через свій плащ.");
}
}
public class Main {
public static void main(String[] args) {
Batcave batman = new Batman();
batman.fightCrime(); // Бетмен вирушає на місію!
System.out.println("\n");
Batcave robin = new Robin();
robin.fightCrime(); // Робін намагається свою першу самостійну місію!
}
}
Що тут відбувається?
Batcave
(абстрактний клас): Цей клас має загальну структуру боротьби зі злочинцями, але залишає частину боротьби на розсуд підкласів. Шаблонний метод (fightCrime()
) визначає загальні кроки.fightVillain()
(абстрактний метод): Тут підкласи (як Бетмен чи Робін) можуть додавати свій унікальний підхід — Бетмен використовує гаджети, Робін... ну, намагається, скільки може!- Бетмен і Робін: Ці два класи успадковують від
Batcave
і по-різному реалізують методfightVillain()
. Бетмен — досвідчений професіонал, а Робін... скажімо, ще в процесі навчання.
Чому це важливо?
Патерн Template Design корисний, коли у вас є низка дій, що слідують за однією базовою структурою, але потребують налаштування в окремих частинах.
Як і Бетмен і Робін, вони мають один і той самий шаблон (боротьба зі злочинцями), але те, як вони борються, відрізняється.
Заключні думки
Отже, наступного разу, коли ви побачите Бетмена, який бореться зі злочинцями, пам'ятайте — все це про шаблони. Незалежно від того, чи ви вирішуєте злочини в Готемі, чи проблеми у вашому коді, наявність чіткого шаблону для виконання може заощадити ваш час та енергію (і допомогти не потрапити у неприємну ситуацію з капюшоном у Бетмобілі). Залишайте все простим і дайте вашим підкласам обробити деталі.
Це все, друзі! Тепер вирушайте, боріться зі злочинами у своєму коді та пам'ятайте — завжди використовуйте шаблон.
Перекладено з: Template Design Pattern