To see a story

Internet winter comes, small light feels more and more code farming this line is not quite good to mix. As the end of the year approaches, the feeling of homesickness is also becoming more acute. Bottom of my heart a horizontal, or directly back home to do some small business got ~

Said to do, light quit his job, returned to his hometown Wuhan, started selling hot and dry noodles. Xiao Guang holds the idea of scientific shop, reasonable management, visit the old store, explore the flow of people, and finally opened the store in the software park next to.

After careful he found that everyone point hot dry noodles, to the ingredients are not the same, some to green onion, some don’t green onion to cilantro, some don’t hot, some to add sauerkraut…… Light thought, this can not difficult to me, you want what don’t tell me once, not got. Soon, the hot and dry noodle program comes out:

public class HotDryNoodles { private boolean addShallot; private boolean addParsley; private boolean addChili; private boolean addSauerkraut; public HotDryNoodles(boolean shallot, boolean parsley, boolean chili, boolean sauerkraut) { this.addShallot = shallot; this.addParsley = parsley; this.addChili = chili; this.addSauerkraut = sauerkraut; } @Override public String toString() { StringBuilder builder = new StringBuilder("A bowl of hot-dry noodles has:"); If (this.addShallot) {builder.appEnd (" shallot."); } if (this.addparsley) {builder.append(" coriander "); } if (this.addchili) {builder.append(" chili."); } if (this.addSauerkraut) {builder.append(" sauerkraut "); } return builder.toString(); }}Copy the code

Note: Constructor arguments are sequential (scallion). Coriander. Chili. Pickled cabbage.

You don’t say, wuhan code farmers really love to eat hot and dry noodles, a business will come to the door:

A: Sir, hot and dry noodles with scallions, coriander and sauerkraut. B: Sir, hot and dry noodles with scallions and sauerkraut.

Light, a “good “, immediately start work:

public class XiaoGuang { public static void main(String[] args) { // A HotDryNoodles noodlesA = new HotDryNoodles(true, true, false, true); System.out.println("Customer A wants: " + noodlesA); // B HotDryNoodles noodlesB = new HotDryNoodles(true, false, false, true); System.out.println("Customer B wants: " + noodlesB); }}Copy the code

Out soon:

Customer A wants: A bowl of hot-dry noodles has. Customer B wants: A bowl of hot dry noodles has: green onion. Sour pickled cabbage.Copy the code

Perfect ~

At this time, came a buddy: boss, a bowl of hot and dry noodles, add pepper, do not put Onions. Light chi chi chi busy work, the result of one end out, people buddy is not happy, how to put green ah, has not put pepper ~~ the original light is mistaken order (parameter order)~ (also blame this buddy not according to the set card)

No way, redo it ~ (for user experience)

After closing the stalls, Xiao Guang is to reflect on the pain ah, the current process is really easy to go wrong ah:

  • At present, the order is fixed, customers have different requirements, and it is easy to make mistakes if they do not follow the routine.
  • The current number is fixed, and most customers choose to default to one or two additional requests.

Thinking about how to improve, light suddenly had an idea:

Isn’t that the problem with building objects with lots of optional arguments? I can use Builder mode to solve this problem. The original programming is everywhere, small light dark think.

Then began the transformation process:

  • He bought a table and used it as a ingredients Builder.
  • Add the ingredients (scallions. Coriander. Peppers, sauerles) from his construction of HotDryNoodlesWithBuilder are on the topping table.
  • Let the customer choose what ingredients to add and choose from the toppings.

So, the process of adding ingredients is programmed to take care of itself:

In this way, he not only releases his own labor, but also does not have to bother to remember what customers want and do not want. Make the basic noodles, put them on the seasoning table, and let users add them by themselves

Hot and dry noodle process after transformation:

public class HotDryNoodlesWithBuilder { private boolean addShallot; private boolean addParsley; private boolean addChili; private boolean addSauerkraut; public HotDryNoodlesWithBuilder(Builder builder) { this.addShallot = builder.addShallot; this.addParsley = builder.addParsley; this.addChili = builder.addChili; this.addSauerkraut = builder.addSauerkraut; } @Override public String toString() { StringBuilder builder = new StringBuilder("A bowl of hot-dry noodles has:"); If (this.addShallot) {builder.appEnd (" shallot."); } if (this.addparsley) {builder.append(" coriander "); } if (this.addchili) {builder.append(" chili."); } if (this.addSauerkraut) {builder.append(" sauerkraut "); } return builder.toString(); } public static class Builder { private boolean addShallot; private boolean addParsley; private boolean addChili; private boolean addSauerkraut; public Builder() { } public Builder withShallot() { this.addShallot = true; return this; } public Builder withParsley() { this.addParsley = true; return this; } public Builder withChili() { this.addChili = true; return this; } public Builder withSauerkraut() { this.addSauerkraut = true; return this; } public HotDryNoodlesWithBuilder build() { return new HotDryNoodlesWithBuilder(this); }}}Copy the code

Let’s see how users use it:

public class XiaoGuang {

    public static void main(String[] args) {

        // with builder
        HotDryNoodlesWithBuilder noodlesC = new HotDryNoodlesWithBuilder.Builder()
                .withChili()
                .withParsley()
                .build();
        System.out.println("Customer C wants: " + noodlesC);

        HotDryNoodlesWithBuilder noodlesD = new HotDryNoodlesWithBuilder.Builder()
                .withChili()
                .withParsley()
                .withSauerkraut()
                .withShallot()
                .build();
        System.out.println("Customer D wants: " + noodlesD);
    }
}Copy the code

The results were less than satisfactory:

Customer C wants: A bowl of hot-dry noodles has: coriander. Customer D wants: A bowl of hot-dry noodles has: green onion. Coriander. Chili. Sauerkraut.Copy the code

No users complain that the light is wrong, what you want to add, the order does not matter. Light also has more time to serve more customers… Looking at the coming and going diners, xiao Guang is looking forward to: soon can open branch stores, chain stores, listed, when the chairman of the board, married Bai Fumei, onto the peak of life, ha ha ha ha ha.

After the story

Let’s revisit the GoF Design Mode Builder mode:

builde

The Buidler pattern is a creative design pattern. It is often used to separate the construction process of a complex object so that the user can choose the creation process as needed. In addition, when the construction of this complex object contains many optional parameters, the Builder mode is the best choice.

From this story, we can see that when the ingredients of hot and dry noodles have too many parameters, it is difficult for us to control them. Once the parameters are wrong, customers will not be able to accept them

Let’s look at the relationship between the reconstructed process and the Builder mode in this story:

builder-2

In general, Builders are often implemented as static inner classes of the real product (to improve cohesion). So Product, Director, Builder is often in a class file, for example, in this case HotDryNoodlesWithBuilder. Java. In order to better relate the class diagram of HotDryNoodlesWithBuilder, two ~ are drawn.

Further reading

As a Java/Android developer, if you want to design a generic library, the Builder pattern is almost certainly one to use, and we need to provide a good entry/interface so that users can flexibly construct the objects they need.

OkHttpClient () : OkHttpClient () : OkHttpClient () : OkHttpClient () : OkHttpClient

public class OkHttpClient implements Cloneable, Call.Factory { public OkHttpClient() { this(new Builder()); } private OkHttpClient(Builder builder) { this.dispatcher = builder.dispatcher; this.proxy = builder.proxy; this.protocols = builder.protocols; this.connectionSpecs = builder.connectionSpecs; this.interceptors = Util.immutableList(builder.interceptors); this.networkInterceptors = Util.immutableList(builder.networkInterceptors); this.proxySelector = builder.proxySelector; this.cookieJar = builder.cookieJar; this.cache = builder.cache; this.internalCache = builder.internalCache; this.socketFactory = builder.socketFactory; // more code... } public static final class Builder { public Builder() { ... } public Builder cache(Cache cache) { ... } public Builder dispatcher(Dispatcher dispatcher) { ... } public Builder protocols(List protocols) { ... } public List networkInterceptors() { ... } public Builder addNetworkInterceptor(Interceptor interceptor) { ... } public OkHttpClient build() { return new OkHttpClient(this); }}}Copy the code

Does it look like HotDryNoodlesWithBuilder designed by Little Light…

Life will continue, xiao Guang continue to struggle, looking forward to their own peak dream ~