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.
import org.apache.http.client.fluent.Request;
import java.io.IOException;
...
String html = null;
try {
html = Request.Get("http://www.qualysite.co.jp/")
.connectTimeout(1000)
.socketTimeout(1000)
.execute()
.returnContent()
.asString();
} catch (IOException e) {
...
}
It is a scene to get the source (HTML) of the URL specified by the argument, but when I watch it again, I am fascinated by the beauty of the interface that is intuitively transmitted.
It's easy to look at the fluid interface, but the designers say, "It's such a decoration. Great people don't understand it [^ 1]". The point of appreciation here is the functional beauty that summarizes the HTTP connection routine, which has many steps, in an easy-to-understand and simple manner. Let's enjoy it together below.
The code at the beginning is an example of using the HTTP client Apache HttpComponents HttpClient, which seems to be the most famous in Java. Version 4.3, released in 2013, added an interface like the one at the beginning to this library.
Prior to that, you had to write code with many steps to get the same result:
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
...
String html = null;
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpGet httpGet = new HttpGet("http://www.qualysite.co.jp/");
//Request settings
RequestConfig requestConfig = RequestConfig.custom()
.setSocketTimeout(1000)
.setConnectTimeout(1000)
.build();
httpGet.setConfig(requestConfig);
CloseableHttpResponse response = null;
try {
response = httpClient.execute(httpGet);
//Content acquisition(Entity object holds Content)
HttpEntity entity = response.getEntity();
//Get source from Content
html = EntityUtils.toString(entity, StandardCharsets.UTF_8);
//Entity consumption
EntityUtils.consume(entity);
} catch(IOException e) {
...
} finally {
try {
if (response != null) {
//Response close
response.close();
}
} catch (IOException e) {
...
}
}
Coding is a superficial problem with such code. The real problem is that it's easy to make mistakes when writing code. It's a mistake to ** have to take a number of steps in sequence from the start to the end of an HTTP connection ** and ** it's hard to tell which step you have to perform ** It will be the cause.
In particular,
//Entity consumption
EntityUtils.consume(entity); //Internally closes InputStream
Or
//Response close
response.close(); //Internally closes HTTP connection
Does not cause an error at build or run, so if you don't understand how it's built, you'll easily forget to write it. It is not common to say "Entity must be consumed" or "Response must be closed". This forgetting to write causes a resource leak.
Also, since CloseableHttpClient
implements the Closeable interface, it is possible to writehttpClient.close ();
. Is it okay to not call the method that closes HttpClient like this? It is not called in Official sample source, so I think it is unnecessary, but I am worried.
HttpClient provides a lot of features at a low level and is used in many libraries, but it's not beautiful to use this code as it is in cases where it is not necessary.
The code at the beginning uses the Facade pattern. Let's take a look again with comments.
import org.apache.http.client.fluent.Request;
import java.io.IOException;
...
String html = null;
try {
html = Request.Get("http://www.qualysite.co.jp/")
.connectTimeout(1000) //Request settings
.socketTimeout(1000) //Request settings
.execute()
.returnContent() //Content acquisition->Reponse close->Entity consumption
.asString(); //Get source from Content
} catch (IOException e) {
...
}
Of note is the Response # returnContent
method. With this one method, Content acquisition-> Reponse close-> Entity consumption, ** steps that must be performed ** in the process using multiple objects **, ** in order **, ** collectively ** Can be processed.
This method does three things, but the point is that the method name is returnContent
. The class designer probably didn't want the class user to be aware of the handling of Answer closing and Entity consumption. Because it is not included in the method. However, if you imagine it further, it seems that you can see the hidden message "It's not just returning a reference to the Content object" where it says returnContent
instead of getContent
.
Facade means "front of the building". The purpose of the Facade pattern is to show users only the front of the building, that is, to bring together the cluttered interfaces of multiple classes and show them to a minimum. No wonder I thought the interface was elegant, but it was the beauty measured by the designer.
Many experts have also commented on the Facade pattern. (I emphasized it in bold.)
Hiroshi Yuki
One programmer is "good at" saying, "Oh, call me before calling this class. You need to register with this class before calling this method." When talking to, it suggests that we need to introduce the Facade role. ["Introduction to Design Patterns Learned in Java Language"](https://www.amazon.co.jp/ Introduction to Design Patterns Learned in Java Language-Yuki-Hiroshi / dp / 4797327030 /)
lang_and_engine
** When calling multiple classes **, collect them in one method as a standard so that you do not have to remember the order of calling. The method is, so to speak, a procedure manual for using multiple classes. From List of 23 GoF design patterns to utilize in Java
It's the real pleasure of programmers to be able to enjoy intellectual enjoyment just by looking at a single line of code without having to go to the museum.
If you are an engineer who sympathizes with the artistry of the Facade pattern, please contact our recruiting staff (Qualysite Technologies Inc.)!
-Design pattern to enjoy with Java library used frequently --Factory pattern -Design patterns to enjoy with frequently used Java libraries --Builder patterns -Design patterns to enjoy with frequently used Java libraries --Abstract Factory pattern
--Design patterns that you can enjoy with your favorite Java library --Facade pattern -Design pattern to enjoy with frequently used Java library --Adapter pattern
-Design patterns to enjoy with frequently used Java libraries --Template Method patterns -Design patterns to enjoy with frequently used Java libraries --Strategy patterns
[^ 1]: One of the quotes that appears in Mobile Suit Gundam. When asked by Char that Zeong had no legs, the mechanic replied, "It's such a decoration. Great people don't know it." ([Zeong](ttps: //ja.wikipedia.org/wiki/Zeong) --Wikipedia)
Recommended Posts