В этом руководстве (и в дальнейшем) мы поговорим о шаблонах проектирования, наиболее часто используемых в Java. Я просмотрел множество руководств, чтобы понять, что это значит, и, будучи ребенком, не имеющим образования в области компьютерных наук, все казалось слишком чуждым! Каждый учебник, который я читал, был либо слишком переполнен жаргонизмами, либо непримиримо убогими примерами клише. Поэтому я взял на себя смелость создать сценарии реального мира и использовать эти шаблоны в качестве решения для них, чтобы я мог лучше понять их.
Не стесняйтесь поправлять меня, если я ошибаюсь, потому что это мои интерпретации шаблонов проектирования и того, как их использовать.
Шаблоны проектирования
Шаблоны проектирования – это набор общих идей, которые можно использовать в определенных условиях, чтобы убедиться, что кодовая база оптимизирована, пригодна для повторного использования и стабильна.
Они действуют как чертежи идей, которые можно настроить в соответствии с потребностями вашего проекта.
Это никогда не бывает обязательной ситуацией, когда мы должны использовать определенный шаблон проектирования, когда иногда простой код справляется с этой задачей.
В зависимости от сложности дизайна или масштаба приложения шаблоны делятся на три основные категории
- Модели создания
- Структурные Закономерности
- Поведенческие паттерны
Сегодня мы поговорим об одном из первых “Шаблонов создания”, то есть о фабричном шаблоне.
Фабричный Паттерн (Творческий Паттерн)
Фабричный шаблон используется для создания объектов с использованием интерфейса, где конечный пользователь получает возможность решить, какой тип объекта он хочет, фактически не беспокоясь о его создании.
Чтобы лучше понять это, давайте возьмем пример из реального мира:
Представьте себе систему уведомлений с несколькими типами доставки, такими как уведомление по электронной почте, SMS-уведомление, Push-уведомление и т.д.
Здесь все системы пытаются выполнить одну и ту же функцию отправки уведомлений конечному пользователю. Но у них будут разные стратегии реализации для достижения этой цели. Вот почему я считаю, что это будет отличным кандидатом для изучения фабричного шаблона.
У нас будет встроенный интерфейс уведомлений, который будет реализован отдельными типами для продолжения их функциональности. А затем мы создадим фабрику, которая будет возвращать подтипы уведомлений в зависимости от выбора конечного пользователя.
Хватит разговоров, давайте погрузимся в код!
Интерфейс уведомлений
public interface Notification { public void sendNotification(NotificationModel notif); }
Это самый важный класс нашего проекта. Это действует как схема всей нашей системы. Этот класс будет иметь все методы, необходимые конечному пользователю, такие как send Message(), GetType(), getMsgInfo() и т.д.
Интерфейс прямо сейчас имеет только один метод, и это sendNotification(Модель уведомления, а не if)
. Где Модель уведомлений
– это простой элементарный POJO, который будет содержать всю основную необходимую информацию.
Модель уведомления
public class NotificationModel { private String to; private String from; private String msg; // Getters and Setters Here ... public NotificationModel(String to, String from, String msg) { this.to = to; this.from = from; this.msg = msg; } @Override public String toString() { return msg + " is sent to " + to + " from " + from; } }
Интерфейс уведомлений затем будет реализован отдельными классами по-разному.
Давайте посмотрим, как мы можем это сделать.
Уведомление по электронной почте
public class EMailNotification implements Notification { @Override public void sendNotification(NotificationModel notif) { System.out.println("E-Mail Notification is going out\n" + notif + "\n"); } }
Прямо сейчас все, что делает наш класс emailNotification, – это выводит некоторую информацию на консоль. Вместе со всей информацией о pojo уведомлений. Мы будем продолжать в том же духе, чтобы сосредоточиться на приведенном здесь руководстве.
Аналогичным образом, мы также создадим вспомогательные функции SMS-уведомлений и PushNotification
SMS-уведомление
public class SMSNotification implements Notification { @Override public void sendNotification(NotificationModel notif) { System.out.println("SMS Notification is going out\n" + notif + "\n"); } }
Push-уведомление
public class PushNotification implements Notification { @Override public void sendNotification(NotificationModel notif) { System.out.println("Push Notification is going out\n" + notif + "\n"); } }
Мы также создадим Тип уведомления
перечисление, чтобы конечному пользователю было проще при использовании фабрики создавать подклассы уведомлений.
Тип уведомления
public enum NotificationType { SMS, EMAIL, PUSH }
Теперь, наконец, мы создадим наш фабричный класс, который будет отвечать за передачу необходимого класса уведомлений конечному пользователю.
Фабрика уведомлений
public class NotificationFactory { public Notification createNotification(NotificationType type) { Notification notification; switch(type) { case EMAIL: notification = new EMailNotification(); break; case PUSH: notification = new PushNotification(); break; case SMS: default: notification = new SMSNotification(); break; } return notification; } }
Здесь пользователь передаст тип уведомления, который определит, какой вариант интерфейса уведомлений будет возвращен. А затем, используя унифицированную сигнатуру метода, мы можем упростить остальную часть реализации.
А затем, используя унифицированную сигнатуру метода, мы можем упростить остальную часть реализации.
public class Main { public static void main(String[] args) { NotificationModel smsNotif = new NotificationModel("1234567895", "1234567899", "Hey There!"); Notification smsNotification = new NotificationFactory() .createNotification(NotificationType.SMS); NotificationModel emailNotif = new NotificationModel( "to.test@gmail.com", "from.test@gmail.com", "Hey There!"); Notification emailNotification = new NotificationFactory() .createNotification(NotificationType.EMAIL); NotificationModel pushNotif = new NotificationModel("VPA12345", "VPA90585749", "Hey There!"); Notification pushNotification = new NotificationFactory() .createNotification(NotificationType.PUSH); smsNotification.sendNotification(smsNotif); emailNotification.sendNotification(emailNotif); pushNotification.sendNotification(pushNotif); } }
Когда мы запускаем эту программу, это вывод, который мы получаем в консоли
SMS Notification is going out Hey There! is sent to 1234567895 from 1234567899 E-Mail Notification is going out Hey There! is sent to to.test@gmail.com from from.test@gmail.com Push Notification is going out Hey There! is sent to VPA12345 from VPA90585749
Примечание: когда мы внимательно рассмотрим этот пример, мы сможем понять, что это не что иное, как интерфейс и стратегия его реализации. И мы используем класс с именем factory для получения требуемых экземпляров. Так зачем же проходить через всю эту боль?
Мы могли бы позволить заказчику выбрать подкласс и вызвать необходимый конструктор, верно?
Что ж, это может быть так, но по мере роста приложения и увеличения количества типов уведомлений конечному пользователю становится все сложнее отслеживать их. Таким образом, методология factory становится более простой и достаточно абстрактной, чтобы конечный пользователь мог вызывать наши API.
По мере того как ваше приложение растет и становится все более и более сложным. Повторяющиеся шаблоны начинают создавать проблемы и узкие места, и мы можем использовать эти схемы шаблонов проектирования для их решения.
Надеюсь, вы все отлично провели время, просматривая статью. Пожалуйста, дайте мне знать, если это было полезно.
Весь код, который мы обсудим в этой серии, также будет присутствовать в моем проекте github.
Фабричный шаблон – Github
Проект Шаблона Базового Дизайна – Github
Мои дни наполнены кофе и только кофе. Так что я знаю, ты знаешь, что мы все должны делать 🤞
Оригинал: “https://dev.to/akhilarjun/factory-pattern-java-design-patterns-5h33”