Home>

Foreword

This article mainly introduces how to implement the builder mode. When you build large objects,Objects have more attributes,We can use a constructor or use an empty constructor,Then use the setter method to set it.When users use these methods,There will be many lengthy constructor parameter lists or setter methods. We can use the builder pattern to simplify the construction of large objects,Improve the simplicity of the code,At the same time improve the user's coding experience.

Below we will introduce the builder mode before java8, using the minimal code tool lombok, and after java8.

pre java8

Let's take a look at the builder mode before java8

public class order {
 private string code;
 private list<string>offers;
 private map<string, object>features;
 public static order.builder builder () {
  return new builder ();
 }
 //Omit getter setter
 public static class builder {
  private orderstate orderstate=new orderstate ();
  private static final beancopier ordercopier=beancopier.create (orderstate.class, order1.class, false);
  private class orderstate {
   private string code;
   private map<string, object>features;
   private list<string>offers;
   //Omit getter setter
  }
  public builder code (string code) {
   orderstate.code=code;
   return this;
  }
  public builder features (map<string, object>features) {
   orderstate.features=features;
   return this;
  }
  public<t>builder feature (string key, t obj) {
   if (orderstate.features == null) {
    orderstate.features=new hashmap<>();
   }
   orderstate.features.put (key, obj);
   return this;
  }
  public builder offers (list<string>offers) {
   orderstate.offers=offers;
   return this;
  }
  public builder offer (string offer) {
   if (orderstate.offers == null) {
    orderstate.offers=new arraylist<>();
   }
   orderstate.offers.add (offer);
   return this;
  }
  public order build () {
   order order=new order ();
   ordercopier.copy (orderstate, order1, null);
   orderstate=null;
   return order;
  }
 }
}

The above code looks verbose.And ide does not provide automatic generation tools,This is also one of the reasons why we see relatively few such patterns in engineering code.But for users of this class,Improved high code experience.At the user,When using this class:

order order=order.builder (). code ("1235")
  .offer ("50 minus 5")
  .feature ("category", "shoe")
  .build ();

A class definition usually has only one place,There are many places to use this class,Think more about the user when defining the class,Can improve efficiency for developers using this class,At the same time, the code of the entire team becomes more concise.

I always think that the design of a class is the same as the designer of a product.Product managers design a feature that first addresses users ’pain points,While also improving the user experience,Keep users cool.Also design a base class,Need to solve a business problem,At the same time, from the perspective of the user,Keep users cool.A good basic class designer needs a little product thinking,The code is your product.

lombok

For the users of the class,It ’s cool to use,But for class developers,Not friendly enough,And there will be a lot of seemingly duplicate code.For class developers,This class is difficult to maintain.For developers,Never do duplicate things,Since this thing is regular and repetitive. For something like this,The program is better.

lombok is a tool that can make java code more concise and make your development more efficient.After using lombok, we don't need to write getter&setter, tostring, etc. These can be replaced by annotationsDuring compilation,lombok will help you generate the corresponding bytecode.So don't worry about performance loss.

lombok also supports the builder mode, you can replace the redundant code with a few comments.

@builder
public class order {
 private string code;
 @singular
 private list<string>offers;
 @singular
 private map<string, object>features;
}

When we use

order order=order.builder (). code ("1234")
   .offer ("50 minus 5")
   .feature ("category", "category")
   .build ();

Above we have used @builder, @singular to achieve the above lengthy code.Isn't it terse?During the compilation phase,Will help us generate the same bytecode as the verbose code above.

When developing,lombok needs the support of ide plugin,So if you use it in engineering code,Need the team to reach consensus,And install the plugin.

java8

After using java8, we have a new method for the builder mode,We can use supplier and consumer to construct a general builder pattern. The specific code is as follows:

public class genericbuilder<t>{
 private final supplier<t>instantiator;
 private list<consumer<t>>instantiatormodifiers=new arraylist<>();
 private list<consumer>t>keyvaluemodifiers=new arraylist<>();
 public genericbuilder (supplier<t>instantiator) {
  this.instantiator=instantiator;
 }
 public static<t>genericbuilder<t>of (supplier<t>instantiator) {
  return new genericbuilder<t>(instantiator);
 }
 public<u>genericbuilder<t>with (biconsumer<t, u>consumer, u value) {
  consumer<t>c=instance->consumer.accept (instance, value);
  instantiatormodifiers.add (c);
  return this;
 }
 public<k, v>genericbuilder<t>with (keyvalueconsumer<t, k, v>consumer, k key, v value) {
  consumer<t>c=instance->consumer.accept (instance, key, value);
  keyvaluemodifiers.add (c);
  return this;
 }
 public t build () {
  t value=instantiator.get ();
  instantiatormodifiers.foreach (modifier->modifier.accept (value));
  keyvaluemodifiers.foreach (keyvaluemodifier->keyvaluemodifier.accept (value));
  instantiatormodifiers.clear ();
  keyvaluemodifiers.clear ();
  return value;
 }
}

order class definition

public class order {
 private string code;
 private list<string>offers;
 private map<string, object>features;
 public void addoffer (string offer) {
  offers=optional.ofnullable (offers)
    .orelseget (arraylist ::new);
  offers.add (offer);
 }
 public<t>void addfeature (string key, t value) {
  features=optional.ofnullable (features)
    .orelseget (hashmap ::new);
  features.put (key, value);
 }
 //Omit getter setter
}

When used:

order order=genericbuilder.of (order ::new)
     .with (order ::setcode, "123232")
     .with (order ::addoffer, "minus 5 for 100")
     .with (order ::addfeature, "category", "shoe")
     .build ();

In java8, using the general builder method simplifies code development,Compared with pre java8, it is much simpler.Compared to lombok, because getter&setter methods are still generated, lombok is still not concise. But it uses the features of java8 and does not need to provide additional third package support.

to sum up

  • Previous Laravel implements the autoload method
  • Next Android ViewonMeasure method explained and examples