Припиніть хардкодити: Використовуйте Factory Method для рефакторингу вашої системи сповіщень (приклад на Java)
Чи доводилося вам коли-небудь тонути в блоках if-else просто для того, щоб відправити просте повідомлення? Це ознака того, що настав час впровадити патерн проектування Factory Method.
У цій статті я проведу вас через реалістичний і простий приклад на Java: рефакторинг системи сповіщень, яка була захардкожена і негнучка, а стала гнучкою і легко розширюваною.
Проблема: Безладний, негнучкий код
Припустимо, ви хочете відправляти сповіщення. Спочатку це лише email, тому код виглядає нормально. Але потім ви додаєте SMS... а завтра, можливо, Slack, Push, WhatsApp або навіть API для голубиної пошти.
Старий код:
public class NotificationService { public void sendNotification(String type, String message) { if (type.equals("EMAIL")) { System.out.println("Sending EMAIL: " + message); } else if (type.equals("SMS")) { System.out.println("Sending SMS: " + message); } else { throw new IllegalArgumentException("Unknown notification type: " + type); } } public static void main(String[] args) { NotificationService service = new NotificationService(); service.sendNotification("EMAIL", "Welcome to the system!"); service.sendNotification("SMS", "Your code is 1234."); } }
Що тут не так?
- Не масштабується: Кожен новий тип сповіщення = новий блок if.
- Порушує принцип відкритості/закритості: Ви повинні модифікувати існуючий метод для додавання нової поведінки.
- Важко тестувати: Логіка тісно пов’язана і захардкожена.
Рішення: Factory Method
Давайте відрефакторимо цей код, використовуючи патерн Factory Method. Ідея полягає в тому, щоб відокремити створення об’єктів від їх використання.
1. Визначте спільний інтерфейс:
public interface Notification { void notifyUser(String message); }
2. Створити конкретні реалізації:
public class EmailNotification implements Notification { @Override public void notifyUser(String message) { System.out.println("Sending EMAIL: " + message); } } public class SMSNotification implements Notification { @Override public void notifyUser(String message) { System.out.println("Sending SMS: " + message); } }
3. Визначити фабрику:
public abstract class NotificationFactory { public abstract Notification createNotification(); }
4. Реалізувати конкретні фабрики:
public class EmailNotificationFactory extends NotificationFactory { @Override public Notification createNotification() { return new EmailNotification(); } } public class SMSNotificationFactory extends NotificationFactory { @Override public Notification createNotification() { return new SMSNotification(); } }
5. Відрефакторити клієнтський код:
public class NotificationService { public void send(NotificationFactory factory, String message) { Notification notification = factory.createNotification(); notification.notifyUser(message); } public static void main(String[] args) { NotificationService service = new NotificationService(); service.send(new EmailNotificationFactory(), "Welcome to the system!"); service.send(new SMSNotificationFactory(), "Your code is 1234."); } }
Переваги такого підходу
- Принцип відкритості/закритості: Щоб додати Slack або Push — просто створіть новий клас і фабрику. Не потрібно модифікувати існуючу логіку.
- Розділення обов’язків: Створення об’єктів відокремлено від їх використання.
- Легше тестування: Ви можете створювати моки або заглушки для фабрик або сповіщень.
Бонус: Динамічний вибір фабрики
Якщо ви все ще хочете якусь динамічну поведінку (наприклад, на основі рядкового вводу):
public class NotificationFactoryProvider { public static NotificationFactory getFactory(String type) { return switch (type) { case "EMAIL" -> new EmailNotificationFactory(); case "SMS" -> new SMSNotificationFactory(); default -> throw new IllegalArgumentException("Unknown type"); }; } }
Використання:
NotificationFactory factory = NotificationFactoryProvider.getFactory("EMAIL"); NotificationService service = new NotificationService(); service.send(factory, "Hello!");
Заключні думки
Вам не потрібно одразу переходити до складних патернів. Але коли ваші блоки if-else починають розмножуватися, це ознака того, що вам потрібен Factory Method.
Цей патерн допомагає підтримувати ваш код гнучким, тестованим і легким для розширення — і це велика перевага.
Оригінал статті тут: medium.com/...java-example-5c9cecc58ee1
Відгуки та коментарі вітаються! Буду дуже радий зворотньому зв’язку!
13 коментарів
Додати коментар Підписатись на коментаріВідписатись від коментарів