Fun on the design pattern 5: Builder mode (Builder Pattern)

  The builder pattern often used in programming, the following is an overview of the builder mode.

  It is intended: to construct a complex representation its phase separation, so that the same build process can create different representations.

  Mainly to solve: the main solution in the software system, sometimes faced "a complex object" to create work, which usually consists of various parts of sub-objects with a certain algorithm; due to changes in demand, the various parts of this complex subject often face a drastic change, but the algorithm combining them is relatively stable.

  When to use: some of the basic components does not change, and time combinations change frequently.

  How to solve: the changed and unchanged separated.

  The key code: Builder: Create and provide examples, Director: dependency management to build out of the instance.

  Application Example:  1, to Kentucky, Hamburg, cola, french fries, fried chicken and the like are the same, and combinations thereof are constantly changing, generating so-called "package." 2, JAVA in StringBuilder.

 

  To say complex, in fact, a very simple to achieve.

  With the standard mode is similar, except that the builder pattern can be directly combined with the complex itself.

  Most systems have a Java web MySQL table rotation component entity class, the entity directly to the generated class setter return type to the entity class itself, returns the object into itself (the this), a combination of properties is, a class can be made builder, with similar builder may place the object attribute invokes this function chain; except that the User is not itself a separate builder, and not delay build (construct the object).

 1 public class User {
 2 
 3     private Integer id;
 4 
 5     private String password;
 6 
 7     private String username;
 8 
 9     private Integer userIdentity;
10 
11     private String userMobile;
12     
13     private String classId;
14 
15     /**
16      * 班级ID
17      */
18     @Column(name = "`class_id`")
19     @ApiModelProperty(value = "班级ID(id1,id2,id3...)",example = "班级ID(id1,id2,id3...)",required = false)
20     private String classId;
21 
22     public Integer getId() {
23         return id;
24     }
25 
26     public User setId(Integer id) {
27         this.id = id;
28         return this;
29     }
30 
31     public String getPassword() {
32         return password;
33     }
34 
35     public User setPassword(String password) {
36         this.password = password;
37         return this;
38     }
39 
40     public String getUsername() {
41         return username;
42     }
43 
44     public User setUsername(String username) {
45         this.username = username;
46         return this;
47     }
48 
49     public Integer getUserIdentity() {
50         return userIdentity;
51     }
52 
53     public User setUserIdentity(Integer userIdentity) {
54         this.userIdentity = userIdentity;
55         return this;
56     }
57 
58     public String getUserMobile() {
59         return userMobile;
60     }
61     
62     public User setUserMobile(String userMobile) {
63         this.userMobile = userMobile;
64         return this;
65     }
66 
67     public String getClassId() {
68         return classId;
69     }
70     
71     public User setClassId(String classId) {
72         this.classId = classId;
73         return this;
74     }
75 }
User entity class of builder

  (Of course, this is not recommended in this way, usually with withXXX this function name format, setXXX with this non-compliant)

  

  Of course, we do have problems. If the User not simply use in a local program, but also need to request an external return data (here, the entity class builder of may MySQL interact with), and returns different data structure in the request of the entity class (many requests rest API of is one such data structure), but also separate entity class and region builder response to the request. User's builder would write:

 1 public class UserBuilder {
 2 
 3     private Integer id;
 4 
 5     private String password;
 6 
 7     private String username;
 8 
 9     private Integer userIdentity;
10 
11     private String userMobile;
12     
13     private String classId;
14 
15     public User build(){
16         User user = new User();
17         user.id = id;
18         user.password = password;
19         user.username = username;
20         user.userIdentity = userIdentity;
21         user.userMobile = userMobile;
22         user.classId = classId;
23         return user;
24     }
25     
26     /**
27      * 班级ID
28      */
29     @Column(name = "`class_id`")
30     @ApiModelProperty(value = "班级ID(id1,id2,id3...)",example = "班级ID(id1,id2,id3...)",required = false)
31     private String classId;
32 
33     public Integer getId() {
34         return id;
35     }
36 
37     public User withId(Integer id) {
38         this.id = id;
39         return this;
40     }
41 
42     public String getPassword() {
43         return password;
44     }
45 
46     public User withPassword(String password) {
47         this.password = password;
48         return this;
49     }
50 
51     public String getUsername() {
52         return username;
53     }
54 
55     public User withUsername(String username) {
56         this.username = username;
57         return this;
58     }
59 
60     public Integer getUserIdentity() {
61         return userIdentity;
62     }
63 
64     public User withUserIdentity(Integer userIdentity) {
65         this.userIdentity = userIdentity;
66         return this;
67     }
68 
69     public String getUserMobile() {
70         return userMobile;
71     }
72     
73     public User withUserMobile(String userMobile) {
74         this.userMobile = userMobile;
75         return this;
76     }
77 
78     public String getClassId() {
79         return classId;
80     }
81     
82     public User withClassId(String classId) {
83         this.classId = classId;
84         return this;
85     }
86 }
Real builder

  User can customize the corresponding data structure in accordance returned.

  

  In another case, the request data structure is complex, there are certain properties and dictionary array, similar to the case of the production of cars, some of which are not part of the standard, pre must build a good (corresponding to certain attributes dictionary), and some more than one further component (corresponding to the array under certain properties), if you want to modify some of the components, the components must also be associated with changes (modifications within the attributes associated with the object), then it is necessary to set the class given a set of property-related function well.

  Like builder connection kubernetes create a copy of the controller (replicationController), it uses a bulk provisioning of complex objects function.

  Create a builder copy controller:

 1 package io.kubernetes.client.models;
 2 
 3 import io.kubernetes.client.fluent.*;
 4 
 5 public class V1ReplicationControllerBuilder extends V1ReplicationControllerFluentImpl<V1ReplicationControllerBuilder> implements VisitableBuilder<V1ReplicationController, V1ReplicationControllerBuilder>
 6 {
 7     V1ReplicationControllerFluent<?> fluent;
 8     Boolean validationEnabled;
 9     
10     public V1ReplicationControllerBuilder() {
11         this(Boolean.valueOf(true));
12     }
13     
14     public V1ReplicationControllerBuilder(final Boolean validationEnabled) {
15         this(new V1ReplicationController(), validationEnabled);
16     }
17     
18     public V1ReplicationControllerBuilder(final V1ReplicationControllerFluent<?> fluent) {
19         this(fluent, Boolean.valueOf(true));
20     }
21     
22     public V1ReplicationControllerBuilder(final V1ReplicationControllerFluent<?> fluent, final Boolean validationEnabled) {
23         this(fluent, new V1ReplicationController(), validationEnabled);
24     }
25     
26     public V1ReplicationControllerBuilder(final V1ReplicationControllerFluent<?> fluent, final V1ReplicationController instance) {
27         this(fluent, instance, true);
28     }
29     
30     public V1ReplicationControllerBuilder(final V1ReplicationControllerFluent<?> fluent, final V1ReplicationController instance, final Boolean validationEnabled) {
31         (this.fluent = fluent).withApiVersion(instance.getApiVersion());
32         fluent.withKind(instance.getKind());
33         fluent.withMetadata(instance.getMetadata());
34         fluent.withSpec(instance.getSpec());
35         fluent.withStatus(instance.getStatus());
36         this.validationEnabled = validationEnabled;
37     }
38     
39     public V1ReplicationControllerBuilder(final V1ReplicationController instance) {
40         this(instance, Boolean.valueOf(true));
41     }
42     
43     public V1ReplicationControllerBuilder(final V1ReplicationController instance, final Boolean validationEnabled) {
44         ((V1ReplicationControllerFluentImpl<V1ReplicationControllerFluent>)(this.fluent = this)).withApiVersion(instance.getApiVersion());
45         this.withKind(instance.getKind());
46         this.withMetadata(instance.getMetadata());
47         this.withSpec(instance.getSpec());
48         this.withStatus(instance.getStatus());
49         this.validationEnabled = validationEnabled;
50     }
51     
52     @Override
53     public V1ReplicationController build() {
54         final V1ReplicationController buildable = new V1ReplicationController();
55         buildable.setApiVersion(this.fluent.getApiVersion());
56         buildable.setKind(this.fluent.getKind());
57         buildable.setMetadata(this.fluent.getMetadata());
58         buildable.setSpec(this.fluent.getSpec());
59         buildable.setStatus(this.fluent.getStatus());
60         return buildable;
61     }
62     
63     @Override
64     public boolean equals(final Object o) {
65         if (this == o) {
66             return true;
67         }
68         if (o == null || this.getClass() != o.getClass()) {
69             return false;
70         }
71         if (!super.equals(o)) {
72             return false;
73         }
74         final V1ReplicationControllerBuilder that = (V1ReplicationControllerBuilder)o;
75         Label_0088: {
76             if (this.fluent != null && this.fluent != this) {
77                 if (this.fluent.equals(that.fluent)) {
78                     break Label_0088;
79                 }
80             }
81             else if (that.fluent == null || this.fluent == this) {
82                 break Label_0088;
83             }
84             return false;
85         }
86         if (this.validationEnabled != null) {
87             if (this.validationEnabled.equals(that.validationEnabled)) {
88                 return true;
89             }
90         }
91         else if (that.validationEnabled == null) {
92             return true;
93         }
94         return false;
95     }
96 }
ReplicationControllerBuilder

  Here only declare the constructor and build function, change the property is inherited ReplicationController of:

  1 package io.kubernetes.client.models;
  2 
  3 import com.google.gson.annotations.*;
  4 import io.swagger.annotations.*;
  5 import java.util.*;
  6 
  7 @ApiModel(description = "ReplicationController represents the configuration of a replication controller.")
  8 public class V1ReplicationController
  9 {
 10     @SerializedName("apiVersion")
 11     private String apiVersion;
 12     @SerializedName("kind")
 13     private String kind;
 14     @SerializedName("metadata")
 15     private V1ObjectMeta metadata;
 16     @SerializedName("spec")
 17     private V1ReplicationControllerSpec spec;
 18     @SerializedName("status")
 19     private V1ReplicationControllerStatus status;
 20     
 21     public V1ReplicationController() {
 22         this.apiVersion = null;
 23         this.kind = null;
 24         this.metadata = null;
 25         this.spec = null;
 26         this.status = null;
 27     }
 28     
 29     public V1ReplicationController apiVersion(final String apiVersion) {
 30         this.apiVersion = apiVersion;
 31         return this;
 32     }
 33     
 34     @ApiModelProperty("APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources")
 35     public String getApiVersion() {
 36         return this.apiVersion;
 37     }
 38     
 39     public void setApiVersion(final String apiVersion) {
 40         this.apiVersion = apiVersion;
 41     }
 42     
 43     public V1ReplicationController kind(final String kind) {
 44         this.kind = kind;
 45         return this;
 46     }
 47     
 48     @ApiModelProperty("Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds")
 49     public String getKind() {
 50         return this.kind;
 51     }
 52     
 53     public void setKind(final String kind) {
 54         this.kind = kind;
 55     }
 56     
 57     public V1ReplicationController metadata(final V1ObjectMeta metadata) {
 58         this.metadata = metadata;
 59         return this;
 60     }
 61     
 62     @ApiModelProperty("If the Labels of a ReplicationController are empty, they are defaulted to be the same as the Pod(s) that the replication controller manages. Standard object's metadata. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata")
 63     public V1ObjectMeta getMetadata() {
 64         return this.metadata;
 65     }
 66     
 67     public void setMetadata(final V1ObjectMeta metadata) {
 68         this.metadata = metadata;
 69     }
 70     
 71     public V1ReplicationController spec(final V1ReplicationControllerSpec spec) {
 72         this.spec = spec;
 73         return this;
 74     }
 75     
 76     @ApiModelProperty("Spec defines the specification of the desired behavior of the replication controller. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status")
 77     public V1ReplicationControllerSpec getSpec() {
 78         return this.spec;
 79     }
 80     
 81     public void setSpec(final V1ReplicationControllerSpec spec) {
 82         this.spec = spec;
 83     }
 84     
 85     public V1ReplicationController status(final V1ReplicationControllerStatus status) {
 86         this.status = status;
 87         return this;
 88     }
 89     
 90     @ApiModelProperty("Status is the most recently observed status of the replication controller. This data may be out of date by some window of time. Populated by the system. Read-only. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status")
 91     public V1ReplicationControllerStatus getStatus() {
 92         return this.status;
 93     }
 94     
 95     public void setStatus(final V1ReplicationControllerStatus status) {
 96         this.status = status;
 97     }
 98     
 99     @Override
100     public boolean equals(final Object o) {
101         if (this == o) {
102             return true;
103         }
104         if (o == null || this.getClass() != o.getClass()) {
105             return false;
106         }
107         final V1ReplicationController v1ReplicationController = (V1ReplicationController)o;
108         return Objects.equals(this.apiVersion, v1ReplicationController.apiVersion) && Objects.equals(this.kind, v1ReplicationController.kind) && Objects.equals(this.metadata, v1ReplicationController.metadata) && Objects.equals(this.spec, v1ReplicationController.spec) && Objects.equals(this.status, v1ReplicationController.status);
109     }
110     
111     @Override
112     public int hashCode() {
113         return Objects.hash(this.apiVersion, this.kind, this.metadata, this.spec, this.status);
114     }
115     
116     @Override
117     public String toString() {
118         final StringBuilder sb = new StringBuilder();
119         sb.append("class V1ReplicationController {\n");
120         sb.append("    apiVersion: ").append(this.toIndentedString(this.apiVersion)).append("\n");
121         sb.append("    kind: ").append(this.toIndentedString(this.kind)).append("\n");
122         sb.append("    metadata: ").append(this.toIndentedString(this.metadata)).append("\n");
123         sb.append("    spec: ").append(this.toIndentedString(this.spec)).append("\n");
124         sb.append("    status: ").append(this.toIndentedString(this.status)).append("\n");
125         sb.append("}");
126         return sb.toString();
127     }
128     
129     private String toIndentedString(final Object o) {
130         if (o == null) {
131             return "null";
132         }
133         return o.toString().replace("\n", "\n    ");
134     }
135 }
ReplicationController

  Such relatively simple to achieve both the builder, but without rewriting the code multiplexing entity class corresponding function.

Guess you like

Origin www.cnblogs.com/dgutfly/p/11617867.html