Design patterns to enjoy with frequently used Java libraries --Abstract Factory pattern

GoF design patterns are also hidden in the Java libraries that you use most often. It's easy to overlook the busy daily work, but once in a while, let's take a closer look at the beautiful design, which can be said to be a kind of art.

This art

source file

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Text;
...
    ...
    //Generate new XML document in memory
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = factory.newDocumentBuilder();
    Document document = builder.newDocument();

    //Generate XML elements
    Element element = document.createElement("element");
    Text text = document.createTextNode("text");
    Attr attribute = document.createAttribute("attribute");
    ...

It's a scene where XML documents and elements are generated in Java, but when I watch it again, I find myself in a profound and mysterious interface.

Points of appreciation

Instead of creating a new XML Document instance directly, I'm going through the DocumentBuilderFactory and DocumentBuilder classes. It is an interface of 3 consecutive newXXX reminiscent of Dom's jet stream attack (attack by Dom's pilot trio) [^ 1] that afflicted Gundam with Mobile Suit Gundam, but honestly, redundancy is noticeable. , Doesn't look very beautiful. However, if you read the source code hidden behind it, you may feel something. Let's explore the feelings of the designer together.

When not using the Abstract Factory pattern

Let's start by generating XML documents and elements with the most intuitive code. Please note that the source code for this section contains fictitious classes for illustration purposes.

Factory pattern


//Document corresponds to the Factory class of the element
Document document = new Document();

//Generate XML elements
XMLElement element = document.createXMLElement("element");
XMLText text = document.createXMLTextNode("text");
XMLAttr attribute = document.createXMLAttribute("attribute");
...

There is no particular problem for this purpose only. Now, let's make it possible to generate SOAP [^ 2] elements in addition to XML elements.

Continuation of Factory pattern


//Create SOAP element
SOAPElement element = document.createSOAPElement("element");
SOAPText text = document.createSOAPTextNode("text");
SOAPAttr attribute = document.createSOAPAttribute("attribute");
...

Then, there will be more createXXX ... variations, such as createSOAP .... It's not beautiful to have to add a lot of createXXX ... methods to an existing class (Document) just by adding one more document type such as XML / SOAP.

When using the Abstract Factory pattern

Now let's apply the Abstract Factory pattern. The first is the generation of the XML document.

AbstractFactory pattern (Factory)


//When generating an XML document (Document is equivalent to Factory class)
Document document = new XMLDocument(); //Document subclass

Generate the SOAP document as follows.

AbstractFactory pattern (Factory)


//When generating a SOAP document (Document is equivalent to Factory class)
Document document = new SOAPDocument(); //Document subclass

In either case, the element is generated as follows.

AbstractFactory pattern (things generated by Factory)


//Generate element
Element element = document.createElement("element");
Text text = document.createTextNode("text");
Attr attribute = document.createAttribute("attribute");

Inherit the Document class that corresponds to the abstracted Factory, and create the XMLDocument and SOAPDocument classes that correspond to the concrete Factory. (This class is fictitious.) Then, even if you increase the types of documents such as XML / SOAP, you no longer need to add the createXXX ... method. At the same time, the things generated by Factory (ʻElement, Text, ʻAttr, etc.) are also abstracted, so they can be treated in the same way regardless of the type of element such as XMLElement / SOAPElement. I will. It's simple and beautiful.

The GoF definition of the Abstract Factory pattern is "provides an interface that creates a family of related or dependent objects without specifying their concrete class [^ 3]". The "family of related or dependent objects" here corresponds to ʻElement, Text, and ʻAttr. Also, "an interface generated without specifying its concrete class" is equivalent to Document.

Is the Abstract Factory pattern difficult?

The Abstarct Factory pattern is very simple as mentioned above, but it is often thought to be "difficult". When I was in my first and second year as an engineer, I wasn't quite sure. (Okay, that [Hiroshi Yuki](https://www.amazon.co.jp/%E7%B5%90%E5%9F%8E-%E6%B5%A9/e/B003UW60OA/ref=pd_sim_14_bl_1? _encoding = UTF8 & refRID = YDTDY91X8NYH1QKXNTMF) It is the pattern that I found to be the most difficult.) The reason why I find it difficult is that there are many classes that appear, but more than that, ** it is hard to understand what I am happy with * * I think it is there.

To be honest, in the above example, WEB of the introduction to design patterns, and the example of books, even if you use the Abstract Factory pattern, you are not so happy. There is none. In these, the program is simplified to make the essence of the pattern easier to understand, but the actual benefits of the Abstract Factory pattern are when the program is somewhat complex.

Scenes that can benefit from the Abstract Factory pattern

In conclusion, I think the best scene to benefit from the Abstract Factory pattern is when you want to hide the generation of the abstract Factory class.

The figure is as follows. "Minimum usage" and "How to show your true potential".

AbstractFactory (minimum usage)


|Caller|
↓    ↓
↓ Use ↓ Select Factory to generate
↓    ↓
↓  |Abstract Factory|
↓  |Specific Factory to inherit|
↓    ↓
↓ ↓ Generate
↓    ↓
|Things made with Factory|

AbstractFactory (how to show its true character)


|Caller|
↓    ↓
↓ Use ↓ Use
↓    ↓
↓  |Abstract Factory|
↓    ↓
↓ ↓ Select Factory to generate
↓    ↓
↓  |Specific Factory|
↓    ↓
↓ ↓ Generate
↓    ↓
|Things made with Factory|

The "select and generate Factory" part is different between "minimum usage" and "how to demonstrate its true potential". At a minimum, the caller determines the implementation class of the abstracted Factory. On the other hand, in the real world, the abstracted Factory class uses dynamic class loading [^ 4] and a configuration file to determine the Factory implementation class. Therefore, the caller can replace the concrete Factory implementation class without changing the source code.

Now let's take a look at the code at the beginning of the page again.

//Generate Document corresponding to Element Factory class
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.newDocument();

//Generate element
Element element = document.createElement("element");
Text text = document.createTextNode("text");
Attr attribute = document.createAttribute("attribute");

DocumentBuilderFactory is equivalent to the" Abstract Factory "of the Abstract Factory pattern. The newInstance method creates a" concrete Factory "that is a subclass of this DocumentBuilderFactory. You can choose the specific Factory implementation class from the following vendors.

List of specific Factory implementation classes

These implementation classes are automatically found in the newInstance method of DocumentBuilderFactory in the following order:

Therefore, ** changing the implementation class does not require any changes to the calling code **. I cannot help feeling the artistry of this mechanism.

In addition, two Abstract Factory patterns are hidden in the code at the beginning [^ 5]. Each has the following configuration. (For the word Factory, the thing made by Factory is expressed as Product.)

The first Abstract Factory
Abstract Factory
DocumentBuilderFactory class
Concrete Factory
Classes in the above list ("List of concrete Factory implementation classes")
Abstracted Product
DocumentBuilder class
Specific Product
DocumentBuilder implementation class generated by the classes listed above
Second Abstract Factory
Abstracted Factory
Document
Concrete Factory
Document class generated by the class in the above list ("List of implementation classes of concrete Factory")
Abstracted Product
Element, Text, Attr class
Specific Product
Implementation class of Element, Text, Attr generated by the class in the above list

Expert comments on the Abstract Factory pattern

Many experts have also commented on the Abstract Factory pattern.

Alan Shalloway, James R. Trot

For example, if you are developing a user interface for a system that runs on multiple platforms, you will be using a set of interface objects prepared for each OS you are using. In this way, you can use the Abstract Factory pattern to use different objects depending on the situation.

["Object-oriented mind"](https://www.amazon.co.jp/%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82 % AF% E3% 83% 88% E6% 8C% 87% E5% 90% 91% E3% 81% AE% E3% 81% 93% E3% 81% 93% E3% 82% 8D-SOFTWARE-PATTERNS-% E3% 82% A2% E3% 83% A9% E3% 83% B3-% E3% 82% B7% E3% 83% A3% E3% 83% AD% E3% 82% A6% E3% 82% A7% E3 From% 82% A4 / dp / 4621066048 /)

Jiggs Co., Ltd.

There is a "Factory Method" pattern that is very similar, but the "Factory Method" pattern is a pattern that focuses on the abstraction of "object generation", while the "Abstract Factory" pattern is "related". It is in the abstraction of "Procedures for collectively generating a group of objects to be used".

From IT Senka-Introduction to Design Patterns> Abstract Factory Patterns

Finally

It's the real pleasure of programmers to be able to enjoy intellectual enjoyment by just looking at a few lines of code without having to go to the museum.

If you are an engineer who sympathizes with the artistry of the Abstract Factory pattern, please contact the recruiting staff of our company (Qualysite Technologies Inc.). Please contact me!

Related article

Create an instance

-Design pattern to enjoy with Java library used frequently --Factory pattern -Design patterns to enjoy with frequently used Java libraries --Builder patterns --Design patterns that you can enjoy with your favorite Java library --Abstract Factory pattern

Simplify the interface

-Design patterns to enjoy with Java libraries that are often used --Facade patterns -Design pattern to enjoy with frequently used Java library --Adapter pattern

Leave it to another class

-Design patterns to enjoy with frequently used Java libraries --Template Method patterns -Design patterns to enjoy with frequently used Java libraries --Strategy patterns

Reference URL

[^ 1]: [Black Tertiary Star-Wikipedia](https://ja.wikipedia.org/wiki/Black Tertiary Star) [^ 2]: Protocol for communicating with XML. Used on HTTP. [^ 3]: ["Design pattern for reuse in object orientation"](https://www.amazon.co.jp/%E3%82%AA%E3%83%96%E3%82%B8 % E3% 82% A7% E3% 82% AF% E3% 83% 88% E6% 8C% 87% E5% 90% 91% E3% 81% AB% E3% 81% 8A% E3% 81% 91% E3 % 82% 8B% E5% 86% 8D% E5% 88% A9% E7% 94% A8% E3% 81% AE% E3% 81% 9F% E3% 82% 81% E3% 81% AE% E3% 83 % 87% E3% 82% B6% E3% 82% A4% E3% 83% B3% E3% 83% 91% E3% 82% BF% E3% 83% BC% E3% 83% B3-% E3% 82% AC% E3% 83% B3% E3% 83% 9E-% E3% 82% A8% E3% 83% AA% E3% 83% 83% E3% 82% AF / dp / 479731126 / ref = sr_1_1? Ie = UTF8 & qid = 1495503419 & sr = 8-1 & keywords =% E3% 82% AA% E3% 83% 96% E3% 82% B8% E3% 82% A7% E3% 82% AF% E3% 83% 88% E6% 8C% 87% E5% 90% 91% E3% 81% AB% E3% 81% 8A% E3% 81% 91% E3% 82% 8B% E5% 86% 8D% E5% 88% A9% E7% 94% A8% E3% 81% AE% E3% 81% 9F% E3% 82% 81% E3% 81% AE% E3% 83% 87% E3% 82% B6% E3% 82% A4% E3% 83% B3% E3% 83% From 91% E3% 82% BF% E3% 83% BC% E3% 83% B3) [^ 4]: I wrote it in parentheses, but it's just the Java standard ClassLoader Is a method of creating an instance from a package name and class name that are hard-coded as strings in the source code using. [^ 5]: Strictly speaking, the first Abstract Factory is not the Abstract Factory pattern defined in GoF because there is only one type of abstracted Product, DocumentBuilder.

Recommended Posts

Design patterns to enjoy with frequently used Java libraries --Abstract Factory pattern
Design patterns to enjoy with frequently used Java libraries --Facade pattern
Design patterns to enjoy with frequently used Java libraries --Adapter patterns
Design patterns to enjoy with frequently used Java libraries --Strategy patterns
Design patterns to enjoy with frequently used Java libraries --Template Method patterns
Design patterns learned with Java & PHP (summary)
Design patterns to enjoy with frequently used Java libraries --Adapter patterns
Design patterns to enjoy with frequently used Java libraries --Strategy patterns
Design patterns to enjoy with frequently used Java libraries --Template Method patterns
Design patterns to enjoy with frequently used Java libraries --Facade pattern
Design patterns to enjoy with frequently used Java libraries --Abstract Factory pattern
Design patterns learned with Java & PHP (summary)
Docker. Set frequently used commands to alias "with explanation"
[Updated from time to time] Summary of design patterns in Java
Summary of Chapter 2 of Introduction to Design Patterns Learned in Java Language
Chapter 4 Summary of Introduction to Design Patterns Learned in Java Language
Summary of Chapter 3 of Introduction to Design Patterns Learned in Java Language
[Gang of Four] Design pattern learning --Abstract Factory
Learn the design pattern "Abstract Factory" in Python
Docker. Set frequently used commands to alias "with explanation"
Design Pattern #Factory Method
[Updated from time to time] Summary of design patterns in Java
Let's develop something close to embedded with TDD ~ Design pattern ~
Summary of Chapter 2 of Introduction to Design Patterns Learned in Java Language
Chapter 4 Summary of Introduction to Design Patterns Learned in Java Language
Summary of Chapter 3 of Introduction to Design Patterns Learned in Java Language