Такие читатели, как вы, помогают поддерживать MUO. Когда вы совершаете покупку по ссылкам на нашем сайте, мы можем получать партнерскую комиссию. Читать далее.

Шаблон проектирования factory (или factory method) специализируется на делегировании и инкапсуляции. Этот шаблон позволяет суперклассу откладывать создание экземпляров до подклассов. Это связано с тем, что класс, содержащий шаблон основного фабричного метода, является абстрактным.

Первоначальная версия фабричного метода принимает форму нереализованного метода, потому что он не знает, какой продукт он создаст. Фабричный метод может знать, что он создает какой-то продукт, но он не знает конкретных характеристик продукта, который он создаст. Эти знания доступны только соответствующим подклассам. Следовательно, ответственность за реализацию фабричного метода и создание соответствующих объектов лежит исключительно на подклассе.

Реализация шаблона проектирования Factory в Java

В этой статье используется пример приложения для создания отчета об обратной связи. Это приложение использует различные типы отзывов, которые компания получает (для новой закуски), для создания конкретных отчетов (используя фабричный метод). Таким образом, фабричный шаблон создаст конкретную обратную связь (или отчет об обратной связи), используя в качестве основы следующий основной класс продукта:

instagram viewer

публичныйабстрактныйсортОбратная связь{

частный Нить имя рецензента;
частный Нить отзывСообщение;
частныйинт обзорРейтинги;

публичныйОбратная связь(String reviewerName, String reviewMessage, инт обзорРейтинги){
этот.reviewerName = имя рецензента;
этот.reviewMessage = сообщение обзора;
этот.reviewRatings = обзор рейтингов;
}

публичный Нить getReviewerName(){
возвращаться имя рецензента;
}
публичныйпустотаsetReviewerName(String ReviewerName){
этот.reviewerName = имя рецензента;
}
публичный Нить getReviewMessage(){
возвращаться отзывСообщение;
}
публичныйпустотаsetReviewMessage(строка ReviewMessage){
этот.reviewMessage = сообщение обзора;
}
публичныйинтgetReviewRatings(){
возвращаться обзорРейтинги;
}
публичныйпустотаsetReviewRatings(инт обзорРейтинги){
этот.reviewRatings = обзор рейтингов;
}
}

Каждый отзыв будет иметь три обязательных свойства: имя рецензента, сообщение отзыва и числовой рейтинг (от одного до пяти) для новой закуски. Различные типы отзывов, которые компания получит, будут поступать по одному из трех каналов:

Класс обратной связи по электронной почте

публичныйсортЭлектронная почтаОбратная связьрасширяетОбратная связь{

частный Нить электронная почта рецензента;

общедоступная электронная почтаОтзыв(Нить имя рецензента, Нить обзорСообщение, int обзорРейтинги, Нить рецензентЭлектронная почта) {
супер(reviewerName, reviewMessage, reviewRatings);
этот.reviewerEmail = ReviewerEmail;
}
публичный Нить getReviewerEmail(){
возвращаться электронная почта рецензента;
}
публичныйпустотаsetReviewerEmail(строка ReviewerEmail){
этот.reviewerEmail = ReviewerEmail;
}
}

Класс обратной связи по почте

публичныйсортПочтаОтзывырасширяетОбратная связь{

частный Нить обратный адрес;

общедоступная почтаОтзыв(Нить имя рецензента, Нить обзорСообщение, int обзорРейтинги, Нить обратный адрес) {
супер(reviewerName, reviewMessage, reviewRatings);
этот.returnAddress = обратный адрес;
}

публичный Нить получитьReturnAddress(){
возвращаться обратный адрес;
}

публичныйпустотаsetReturnAddress(Строка возвратаАдрес){
этот.returnAddress = обратный адрес;
}
}

Класс обратной связи в социальных сетях

публичныйсортСоциальные СМИОтзывырасширяетОбратная связь{

частный Нить рецензентHandle;

публичная обратная связь в социальных сетях (Нить имя рецензента, Нить обзорСообщение, int обзорРейтинги, Нить дескриптор рецензента) {
супер(reviewerName, reviewMessage, reviewRatings);
этот.reviewerHandle = обзорерHandle;
}

публичный Нить getReviewerHandle(){
возвращаться рецензентHandle;
}

публичныйпустотаsetReviewerHandle(String ReviewerHandle){
этот.reviewerHandle = обзорерHandle;
}
}

Вы заметите, что каждый подкласс обратной связи имеет уникальное свойство. Это означает, что вам нужно будет создать отчет для каждого типа обратной связи, используя хотя бы одно свойство, уникальное для этого типа.

Простая фабрика

Простая фабрика — это популярный подход к использованию шаблона проектирования фабрики. Этот подход влечет за собой группировку всех различных отзывов (или продуктов) в метод (простая фабрика) и выбор подходящего отзыва на основе параметра.

публичныйсортОтзывОтчетФабрика{

публичный Обратная связь сделатьобратная связь(Тип обратной связи строки){
Обратная связь обратная связь = нулевой;

если(feedbackType.equals("электронная почта")) {
обратная связь = новый Электронная почтаОтзыв();
}ещеесли (feedbackType.equals("почта")) {
обратная связь = новый ПочтаОтзыв();
}ещеесли (feedbackType.equals("Социальное")) {
обратная связь = новый Обратная связь в социальных сетях();
}
возвращаться обратная связь;
}
}

Однако простой фабричный подход не является фабричным шаблоном проектирования и не является шаблоном проектирования. Это больше похоже на дизайнерскую концепцию.

Фабричный метод

Фабричный метод является истинным представлением шаблона проектирования. Используя фабричный метод, реформированный ОтзывОтчетФабрикаJava-класс теперь будет содержать следующий код:

публичныйабстрактныйсортОтзывОтчетФабрика{
публичныйабстрактныйпустотаmakeFeedbackReport(обратная связь);
}

Вы можете определить структуру шаблона проектирования factory с помощью следующей диаграммы классов:

На диаграмме выше вы увидите, что абстрактный класс (или интерфейс) будет содержать абстрактную версию фабричного метода. Таким образом, конкретные фабричные классы, которые расширяют абстрактный класс, будут реализовывать фабричный метод, используя свойства, уникальные для продукта, который он хочет создать. Вы также должны отметить, что любой конкретный класс фабрики должен создавать один или несколько продуктов.

Пример приложения содержит три взаимосвязанных, но уникальных продукта. Каждый тип обратной связи имеет как минимум одно уникальное свойство. Таким образом, приложению потребуется три бетонных завода для производства каждого продукта.

Фабрика обратной связи по электронной почте

публичныйсортЭлектронная почтаОтзывыОтчетрасширяетОтзывОтчетФабрика{

обратная связь по электронной почте;

@Override
публичныйпустотаmakeFeedbackReport(обратная связь){

этот.feedback = (EmailFeedback) отзыв;

Система.вне.println("\nОтчетДляОбратная связьС помощьюЭлектронная почта" +
"\nИмя рецензента: " +этот.feedback.getReviewerName() +
"\nОтзыв: " + этот.feedback.getReviewMessage() +
"\nОценки: " + этот.feedback.getReviewRatings() +
"\nАдрес электронной почты: " + этот.feedback.getReviewerEmail());
}
}

Фабрика обратной связи по почте

публичныйсортMailFeedbackReportрасширяетОтзывОтчетФабрика{
обратная связь по электронной почте;

@Override
публичныйпустотаmakeFeedbackReport(обратная связь){
этот.feedback = (MailFeedback) обратная связь;

Система.вне.println("\nОтчетДляОбратная связьС помощьюПочта" +
"\nИмя рецензента: " +этот.feedback.getReviewerName() +
"\nОтзыв: " + этот.feedback.getReviewMessage() +
"\nОценки: " + этот.feedback.getReviewRatings() +
"\nПочтовый адрес: " + этот.feedback.getReturnAddress());
}
}

Фабрика обратной связи в социальных сетях

публичныйсортСоциальные СМИОтзывыОтчетрасширяетОтзывОтчетФабрика{
Обратная связь в социальных сетях;

@Override
публичныйпустотаmakeFeedbackReport(обратная связь){
этот.feedback = (SocialMediaFeedback) обратная связь;

Система.вне.println("\nОтчетДляОбратная связьС помощьюСоциальноеСМИ" +
"\nИмя рецензента: " + этот.feedback.getReviewerName() +
"\nОтзыв: " + этот.feedback.getReviewMessage() +
"\nОценки: " + этот.feedback.getReviewRatings() +
"\nРецензент в социальных сетях: " + этот.feedback.getReviewerHandle());
}
}

Тестирование примера приложения

Теперь вы можете использовать соответствующие фабричные методы для создания миниатюрных отчетов об обратной связи, полученной из разных каналов. Ты можешь протестировать приложение с помощью JUnit, или вы можете создать класс драйвера:

публичныйсортОсновной{

публичныйстатическийпустотаосновной(строка [] аргументы){
Обратная связь обратная связь = новый Электронная почтаОтзыв("Ник", "Большой продукт!", 5, "ник@email.com");
Обратная связь обратная связь2 = новый ПочтаОтзыв("Джон", «Продукт хороший, но я бы не стал покупать его регулярно», 4, "первая улица");
Обратная связь 3 = новый SocialMediaОтзыв("Джейн", "Это не для меня", 2, "@Джейни");

Фабрика FeedbackReportFactory = новый Электронная почтаОтчет об обратной связи();
ФабрикаОтчетовОбратной связиФабрика2 = новый MailFeedbackReport();
ЗаводОтчетаОбратной связиФабрика3 = новый Отчет об обратной связи по социальным сетям();

фабрика.makeFeedbackReport(обратная связь);
завод2.makeFeedbackReport(обратная связь2);
завод3.makeFeedbackReport(обратная связь3);
}

Приведенный выше класс Main использует соответствующие фабрики для создания трех отчетов, выводя на консоль следующий вывод:

Преимущества использования шаблона проектирования Factory

Шаблон проектирования factory способствует гибкости дизайна, когда вы используете интерфейсы (или абстрактные классы) для создания конкретных классов. Он также способствует масштабируемости за счет полиморфизма, позволяя новым классам реализовывать существующий интерфейс по мере расширения приложения.

Когда вы используете шаблон проектирования factory, вы используете два важных принципа проектирования: открытое-закрытое и инверсия управления (IoC).