Припиніть хардкодити: Використовуйте 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
Відгуки та коментарі вітаються! Буду дуже радий зворотньому зв’язку!

16 коментарів
Додати коментар Підписатись на коментаріВідписатись від коментарів