Builder Pattern
See this code snippnet in Async Http Client project.
1 2 3 4 5 |
AsyncHttpClientConfig cf = new DefaultAsyncHttpClientConfig.Builder() .setProxyServer(new ProxyServer.Builder("127.0.0.1", 38080)).build(); AsyncHttpClient c = new DefaultAsyncHttpClient(cf); |
Builder is like a factory method that is in class scope and to prepare you the instance of the class. The difference is all about how to create the instance. If an instance has many different ways to be composed of, you probably don’t want to code all the possible variations of constructors, right? However, if you simply use setters, you may not have a way to make sure the instance is composed correctly before it is in use. Then, Builder Pattern is a good tool for you. It has all setters return the Builder instance (normally inner class of the subject class). So, the setter operations can be chained together with a final build() to return the parent class instance. For properties not yet set, default will be used.
See Internal
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
public class DefaultAsyncHttpClientConfig implements AsyncHttpClientConfig { // bunch of properties. Once populated it is immutable private final boolean followRedirect; private final int maxRedirects; ... ... // private constructor that only inner class can instantiate private DefaultAsyncHttpClientConfig( boolean followRedirect, int maxRedirects, ...){ ... } ... public static class Builder { //-- bunch of properties private boolean followRedirect = false; private int maxRedirects = 10; ... ... // http public Builder setFollowRedirect(boolean followRedirect) { this.followRedirect = followRedirect; return this; } public Builder setMaxRedirects(int maxRedirects) { this.maxRedirects = maxRedirects; return this; } ... public DefaultAsyncHttpClientConfig build() { return new DefaultAsyncHttpClientConfig( followRedirect, // maxRedirects, // ...); } } } |
There are few things you may notice in this example.
- Separate out config from DefaultAsyncHttpClient.
- The config is created thru builder pattern and it is immutable once constructed.
- Use default for some properties that is not manipulated by developer.
For the DefaultAsyncHttpClient, it has default constructor if you use want to use the default settings. To do that, you can see the code below:
1 2 3 4 |
public DefaultAsyncHttpClient() { this(new DefaultAsyncHttpClientConfig.Builder().build()); } |
Another Example – ThreadFactory
By default, JVM thread dump gives you the naming like pool-N-thread-M, where N stands for pool sequence number and M stands for thread sequence number of the pool. If you want to override it or have threads as daemon, you can use Guava’s ThreadFactoryBuilder as below:
1 2 3 4 5 6 7 8 |
import com.google.common.util.concurrent.ThreadFactoryBuilder; final ThreadFactory threadFactory = new ThreadFactoryBuilder() .setNameFormat("Orders-%d") .setDaemon(true) .build(); final ExecutorService executorService = Executors.newFixedThreadPool(10, threadFactory); |
Connect with us