Шаблонний шаблон проектування

pic

Фото Родіона Куцайєва на Unsplash

Що таке патерн проектування Template?

Уявіть собі Бетмена (так, того самого — героя в плащі!) і Робіна, які намагаються розкрити злочин. Кожного разу, коли вони вирушають на місію, Бетмен робить своє: розслідує місце злочину, бореться з поганцями і видає кумедні репліки. Робін робить те ж саме, але він ще вивчає, як бути супергероєм. Бетмен має чітку рутину, але він настільки щедрий, що дозволяє Робіну робити це по-своєму. Ось і є Template Design Pattern!

Це як шаблон для низки кроків, які повинні виконуватись, але з можливістю налаштування окремих частин підкласами. Тобто, структура залишається незмінною (тому що злочинці — це завжди злочинці), але деталі (як Бетмен бореться з ними, наприклад) можуть змінюватися.

Режим Бетмена = Шаблон

Бетмен має фіксовану рутину боротьби зі злочинцями, але є місця, де він дозволяє Робіну імпровізувати. Ось розбір його шаблону:

  1. Виявити злочин — Бетмен завжди спостерігає за Готемом.
  2. Зустрітися з лиходієм — Жоден злочинець не уникає Бетмена!
  3. Битися з лиходієм — Бетмен має багато класних рухів.
  4. Видавати драматичну репліку — Класика Бетмена. «Я — ніч!»
  5. Зберегти Готем — Зазвичай після цього слідує героїчний вихід.

Тепер поглянемо на шаблон Бетмена:

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