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