作为一名程序开发者,设计模式其实一直有在接触,只是没有专门的去学过,所以可能对设计模式没有一个系统的理解。在一次项目中,需要使用到第三方服务商提供的功能,为了尽快的熟悉其功能代码,在官网下了demo来研究其功能实现,发现一个用来封装消息通知的类是这样写的:
1 package cn.jpush.api.push.model.notification;
2
3 import cn.jpush.api.push.model.PushModel;
4 import cn.jpush.api.utils.Preconditions;
5 import com.google.gson.JsonElement;
6 import com.google.gson.JsonObject;
7 import com.google.gson.JsonPrimitive;
8
9 import java.util.HashSet;
10 import java.util.Map;
11 import java.util.Set;
12
13 public class Notification implements PushModel {
14 private final Object alert;
15 private final Set<PlatformNotification> notifications;
16
17 private Notification(Object alert, Set<PlatformNotification> notifications) {
18 this.alert = alert;
19 this.notifications = notifications;
20 }
21
22 public static Builder newBuilder() {
23 return new Builder();
24 }
25
26 /**
27 * Quick set all platform alert.
28 * Platform notification can override this alert.
29 *
30 * @param alert Notification alert
31 * @return first level notification object
32 */
33 public static Notification alert(Object alert) {
34 return newBuilder().setAlert(alert).build();
35 }
36
37 public static Notification android(String alert, String title, Map<String, String> extras) {
38 return newBuilder()
39 .addPlatformNotification(AndroidNotification.newBuilder()
40 .setAlert(alert)
41 .setTitle(title)
42 .addExtras(extras)
43 .build())
44 .build();
45 }
46
47 public static Notification ios(Object alert, Map<String, String> extras) {
48 return newBuilder()
49 .addPlatformNotification(IosNotification.newBuilder()
50 .setAlert(alert)
51 .addExtras(extras)
52 .build())
53 .build();
54 }
55
56 public static Notification ios_auto_badge() {
57 return newBuilder()
58 .addPlatformNotification(IosNotification.newBuilder()
59 .setAlert("")
60 .autoBadge()
61 .build())
62 .build();
63 }
64
65 public static Notification ios_set_badge(int badge) {
66 return newBuilder()
67 .addPlatformNotification(IosNotification.newBuilder()
68 .setAlert("")
69 .setBadge(badge)
70 .build())
71 .build();
72 }
73
74 public static Notification ios_incr_badge(int badge) {
75 return newBuilder()
76 .addPlatformNotification(IosNotification.newBuilder()
77 .setAlert("")
78 .incrBadge(badge)
79 .build())
80 .build();
81 }
82
83 public static Notification winphone(String alert, Map<String, String> extras) {
84 return newBuilder()
85 .addPlatformNotification(WinphoneNotification.newBuilder()
86 .setAlert(alert)
87 .addExtras(extras)
88 .build())
89 .build();
90 }
91
92 public JsonElement toJSON() {
93 JsonObject json = new JsonObject();
94 if (null != alert) {
95 if(alert instanceof JsonObject) {
96 json.add(PlatformNotification.ALERT, (JsonObject) alert);
97 } else if (alert instanceof IosAlert) {
98 json.add(PlatformNotification.ALERT, ((IosAlert) alert).toJSON());
99 } else {
100 json.add(PlatformNotification.ALERT, new JsonPrimitive(alert.toString()));
101 }
102 }
103 if (null != notifications) {
104 for (PlatformNotification pn : notifications) {
105 if (this.alert != null && pn.getAlert() == null) {
106 pn.setAlert(this.alert);
107 }
108
109 Preconditions.checkArgument(! (null == pn.getAlert()),
110 "For any platform notification, alert field is needed. It can be empty string.");
111
112 json.add(pn.getPlatform(), pn.toJSON());
113 }
114 }
115 return json;
116 }
117
118 public static class Builder {
119 private Object alert;
120 private Set<PlatformNotification> builder;
121
122 public Builder setAlert(Object alert) {
123 this.alert = alert;
124 return this;
125 }
126
127 public Builder addPlatformNotification(PlatformNotification notification) {
128 if (null == builder) {
129 builder = new HashSet<PlatformNotification>();
130 }
131 builder.add(notification);
132 return this;
133 }
134
135 public Notification build() {
136 Preconditions.checkArgument(! (null == builder && null == alert),
137 "No notification payload is set.");
138 return new Notification(alert, builder);
139 }
140 }
141 }
当时使用时,感觉这种设计在使用时挺方便的,尤其是对参数的注入,可能构造一个Natification类所使用的代码有点长,但是对参数的使用十分明了。后来才知道这是Builder设计模式,当构造器需多个参数时,可显著改善可读性。根据此代码,自己也仿照写了相应的代码实现。
1 package com.startup.code.designmode.builder;
2
3 public class Person {
4
5 private Name name;
6
7 private Address address;
8
9 private Person(Builder builder) {
10 this.name = builder.name;
11 this.address = builder.address;
12 }
13
14 @Override
15 public String toString() {
16 return this.name + "--" + this.address;
17 }
18
19 static class Builder{
20
21 private Name name;
22
23 private Address address;
24
25 public Builder name(Name name) {
26 this.name = name;
27 return this;
28 }
29
30 public Builder address(Address address) {
31 this.address = address;
32 return this;
33 }
34
35 public Person build() {
36 return new Person(this);
37 }
38 }
39 }
1 package com.startup.code.designmode.builder;
2
3 public class Name {
4
5 private String firstName; // 姓
6 private String lastName; // 名
7 private String nickName; // 昵称
8 private String usedName; // 曾用名
9
10 @Override
11 public String toString() {
12 return "firstName:" + this.firstName + ",lastName:" + this.lastName + ",nickName:" + this.nickName + ",userdName:" + this.usedName;
13 }
14
15 private Name(Builder builder) {
16 this.firstName = builder.firstName;
17 this.lastName = builder.lastName;
18 this.nickName = builder.nickName;
19 this.usedName = builder.usedName;
20 }
21
22 /**
23 * Name的内部构造类
24 * @author chenq
25 *
26 */
27 static class Builder {
28 private String firstName;
29 private String lastName;
30 private String nickName;
31 private String usedName;
32
33 public Builder firstName(String firstName) {
34 this.firstName = firstName;
35 return this;
36 }
37
38 public Builder lastName(String lastName) {
39 this.lastName = lastName;
40 return this;
41 }
42
43 public Builder nickName(String nickName) {
44 this.nickName = nickName;
45 return this;
46 }
47
48 public Builder usedName(String usedName) {
49 this.usedName = usedName;
50 return this;
51 }
52
53 public Name build() {
54 return new Name(this);
55 }
56 }
57 }
1 package com.startup.code.designmode.builder;
2
3 public class Address {
4
5 private String province; // 省
6 private String city; // 市
7 private String district; // 区县
8
9 private Address(Builder builder) {
10 this.province = builder.province;
11 this.city = builder.city;
12 this.district = builder.district;
13 }
14
15 @Override
16 public String toString() {
17 return "province:" + this.province + ",city:" + this.city + ",district:" + this.district;
18 }
19
20 /**
21 * Address的内部构造类
22 * @author chenq
23 *
24 */
25 static class Builder {
26 private String province;
27 private String city;
28 private String district;
29
30 public Builder province(String province) {
31 this.province = province;
32 return this;
33 }
34
35 public Builder city(String city) {
36 this.city = city;
37 return this;
38 }
39
40 public Builder district(String district) {
41 this.district = district;
42 return this;
43 }
44
45 public Address build() {
46 return new Address(this);
47 }
48 }
49 }
测试类
package com.startup.code.designmode.builder;
public class BuilderTest {
public static void main(String[] args) {
Person person = new Person.Builder()
.address(new Address.Builder().province("江苏省").city("盐城市").district("建湖县").build())
.name(new Name.Builder().firstName("陈").lastName("群").nickName("rocky").usedName("陈大群").build())
.build();
System.out.println(person);
}
}
输出: