Статьи

Пример шаблона фабричного метода проектирования

Эта статья является частью нашего курса Академии под названием « Шаблоны проектирования Java» .

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

1. Введение

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

Основная задача для вас — проанализировать XML и показать его содержимое пользователю. Существуют различные форматы XML в зависимости от типов сообщений, которые компания получает от своих клиентов. Как, например, XML типа заказа имеет разные наборы тегов xml по сравнению с XML ответа или ошибки. Но основная работа та же самая; то есть, чтобы отобразить пользователю сообщение, переносимое в этих XML.

Хотя основная задача та же, используемый объект зависит от типа XML, который приложение получает от пользователя. Таким образом, объект приложения может знать только то, что ему необходим доступ к классу внутри иерархии классов (иерархия различных анализаторов), но он не знает точно, какой класс из набора подклассов родительского класса должен быть выбран.

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

Шаблон метода фабрики, подходящий для этой ситуации, определяет интерфейс для создания объекта, но позволяет подклассам решать, какой класс создавать. Factory Method позволяет классу откладывать создание экземпляров для подклассов.

Давайте посмотрим некоторые подробности о шаблоне метода фабрики, а затем мы будем использовать его для реализации синтаксического анализатора XML для приложения.

2. Что такое шаблон фабричного метода

Фабричный метод Pattern дает нам способ инкапсулировать экземпляры конкретных типов. Шаблон фабричного метода инкапсулирует функциональность, необходимую для выбора и создания экземпляра соответствующего класса внутри назначенного метода, называемого фабричным методом. Фабричный метод выбирает соответствующий класс из иерархии классов на основе контекста приложения и других влияющих факторов. Затем он создает экземпляр выбранного класса и возвращает его как экземпляр типа родительского класса.

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

фигура 1

фигура 1

Товар

  • Определяет интерфейс объектов, которые создает фабричный метод.

ConcreteProduct

  • Реализует интерфейс продукта.

творец

  • Объявляет фабричный метод, который возвращает объект типа Product. Создатель может также определить реализацию по умолчанию метода фабрики, который возвращает объект ConcreteProduct по умолчанию.
  • Может вызвать фабричный метод для создания объекта Product.

ConcreteCreator

  • Переопределяет фабричный метод для возврата экземпляра ConcreteProduct.

Методы фабрики избавляют от необходимости привязывать классы приложений к вашему коду. Код касается только интерфейса продукта; поэтому он может работать с любыми пользовательскими классами ConcreteProduct.

3. Реализация шаблона фабричного метода

Чтобы реализовать решение для приложения, как описано выше, давайте сначала проверим продукт, который мы имеем.

1
2
3
4
5
6
7
package com.javacodegeeks.patterns.factorymethodpattern;
 
public interface XMLParser {
 
    public String parse();
 
}

Вышеупомянутый интерфейс будет использоваться различными парсерами XML.

01
02
03
04
05
06
07
08
09
10
11
package com.javacodegeeks.patterns.factorymethodpattern;
 
public class ErrorXMLParser implements XMLParser{
 
    @Override
    public String parse() {
        System.out.println("Parsing error XML...");
        return "Error XML Message";
    }
 
}

ErrorXMLParser реализует XMLParser и используется для анализа XML-сообщений об ошибках.

01
02
03
04
05
06
07
08
09
10
11
package com.javacodegeeks.patterns.factorymethodpattern;
 
public class FeedbackXML implements XMLParser{
 
    @Override
    public String parse() {
        System.out.println("Parsing feedback XML...");
        return "Feedback XML Message";
    }
 
}

Приведенный выше класс используется для анализа XML-сообщений обратной связи.

Другие парсеры XML:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.javacodegeeks.patterns.factorymethodpattern;
 
public class OrderXMLParser implements XMLParser{
 
    @Override
    public String parse() {
        System.out.println("Parsing order XML...");
        return "Order XML Message";
    }
 
}
 
package com.javacodegeeks.patterns.factorymethodpattern;
 
public class ResponseXMLParser implements XMLParser{
 
    @Override
    public String parse() {
        System.out.println("Parsing response XML...");
        return "Response XML Message";
    }
 
}

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

01
02
03
04
05
06
07
08
09
10
11
12
13
package com.javacodegeeks.patterns.factorymethodpattern;
 
public abstract class DisplayService {
 
    public void display(){
        XMLParser parser = getParser();
        String msg = parser.parse();
        System.out.println(msg);
    }
 
    protected abstract XMLParser getParser();
 
}

Приведенный выше класс используется для отображения сообщения, полученного парсером XML для пользователя. Приведенный выше класс является абстрактным классом, который содержит два важных метода. Метод display используется для отображения сообщения пользователю. Метод getParser — это фабричный метод, который реализуется подклассами для создания экземпляра объекта синтаксического анализатора, а метод используется методом display для анализа XML и получения сообщения для отображения.

Ниже приведены подклассы DisplayService которые реализуют метод getParser .

01
02
03
04
05
06
07
08
09
10
package com.javacodegeeks.patterns.factorymethodpattern;
 
public class ErrorXMLDisplayService extends DisplayService{
 
    @Override
    public XMLParser getParser() {
        return new ErrorXMLParser();
    }
 
}
01
02
03
04
05
06
07
08
09
10
package com.javacodegeeks.patterns.factorymethodpattern;
 
public class FeedbackXMLDisplayService extends DisplayService{
 
    @Override
    public XMLParser getParser() {
        return new FeedbackXML();
    }
 
}
01
02
03
04
05
06
07
08
09
10
package com.javacodegeeks.patterns.factorymethodpattern;
 
public class OrderXMLDisplayService extends DisplayService{
 
    @Override
    public XMLParser getParser() {
        return new OrderXMLParser();
    }
 
}
01
02
03
04
05
06
07
08
09
10
package com.javacodegeeks.patterns.factorymethodpattern;
 
public class ResponseXMLDisplayService extends DisplayService{
 
    @Override
    public XMLParser getParser() {
        return new ResponseXMLParser();
    }
 
}

Теперь давайте проверим заводской метод.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
package com.javacodegeeks.patterns.factorymethodpattern;
 
public class TestFactoryMethodPattern {
 
    public static void main(String[] args) {
        DisplayService service = new FeedbackXMLDisplayService();
        service.display();
 
        service = new ErrorXMLDisplayService();
        service.display();
 
        service = new OrderXMLDisplayService();
        service.display();
 
        service = new ResponseXMLDisplayService();
        service.display();
 
    }
 
}

Приведенный выше класс приводит к следующему выводу:

1
2
3
4
5
6
7
8
Parsing feedback XML...
Feedback XML Message
Parsing error XML...
Error XML Message
Parsing order XML...
Order XML Message
Parsing response XML...
Response XML Message

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

4. Когда использовать шаблон фабричного метода

Используйте шаблон Factory Method, когда

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

5. Шаблон фабричного метода в JDK

Ниже приведены примеры использования шаблона фабричного метода в JDK.

  • java.util.Calendar#getInstance()
  • java.util.ResourceBundle#getBundle()
  • java.text.NumberFormat#getInstance()
  • java.nio.charset.Charset#forName()
  • java.net.URLStreamHandlerFactory#createURLStreamHandler(String) (возвращает одноэлементный объект для протокола)

6. Загрузите исходный код

Это был урок по шаблону фабричного метода. Вы можете скачать исходный код здесь:
FactoryMethodPattern-проект