作为一名程序开发者,设计模式其实一直有在接触,只是没有专门的去学过,所以可能对设计模式没有一个系统的理解。在一次项目中,需要使用到第三方服务商提供的功能,为了尽快的熟悉其功能代码,在官网下了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); } }
输出: