Builder设计模式--改善构造器多个参数时可显著改善可读性
作为一名程序开发者,设计模式其实一直有在接触,只是没有专门的去学过,所以可能对设计模式没有一个系统的理解。在一次项目中,需要使用到第三方服务商提供的功能,为了尽快的熟悉其功能代码,在官网下了demo来研究其功能实现,发现一个用来封装消息通知的类是这样写的:
package cn.jpush.api.push.model.notification; import cn.jpush.api.push.model.PushModel;
import cn.jpush.api.utils.Preconditions;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive; import java.util.HashSet;
import java.util.Map;
import java.util.Set; public class Notification implements PushModel {
private final Object alert;
private final Set<PlatformNotification> notifications; private Notification(Object alert, Set<PlatformNotification> notifications) {
this.alert = alert;
this.notifications = notifications;
} public static Builder newBuilder() {
return new Builder();
} /**
* Quick set all platform alert.
* Platform notification can override this alert.
*
* @param alert Notification alert
* @return first level notification object
*/
public static Notification alert(Object alert) {
return newBuilder().setAlert(alert).build();
} public static Notification android(String alert, String title, Map<String, String> extras) {
return newBuilder()
.addPlatformNotification(AndroidNotification.newBuilder()
.setAlert(alert)
.setTitle(title)
.addExtras(extras)
.build())
.build();
} public static Notification ios(Object alert, Map<String, String> extras) {
return newBuilder()
.addPlatformNotification(IosNotification.newBuilder()
.setAlert(alert)
.addExtras(extras)
.build())
.build();
} public static Notification ios_auto_badge() {
return newBuilder()
.addPlatformNotification(IosNotification.newBuilder()
.setAlert("")
.autoBadge()
.build())
.build();
} public static Notification ios_set_badge(int badge) {
return newBuilder()
.addPlatformNotification(IosNotification.newBuilder()
.setAlert("")
.setBadge(badge)
.build())
.build();
} public static Notification ios_incr_badge(int badge) {
return newBuilder()
.addPlatformNotification(IosNotification.newBuilder()
.setAlert("")
.incrBadge(badge)
.build())
.build();
} public static Notification winphone(String alert, Map<String, String> extras) {
return newBuilder()
.addPlatformNotification(WinphoneNotification.newBuilder()
.setAlert(alert)
.addExtras(extras)
.build())
.build();
} public JsonElement toJSON() {
JsonObject json = new JsonObject();
if (null != alert) {
if(alert instanceof JsonObject) {
json.add(PlatformNotification.ALERT, (JsonObject) alert);
} else if (alert instanceof IosAlert) {
json.add(PlatformNotification.ALERT, ((IosAlert) alert).toJSON());
} else {
json.add(PlatformNotification.ALERT, new JsonPrimitive(alert.toString()));
}
}
if (null != notifications) {
for (PlatformNotification pn : notifications) {
if (this.alert != null && pn.getAlert() == null) {
pn.setAlert(this.alert);
} Preconditions.checkArgument(! (null == pn.getAlert()),
"For any platform notification, alert field is needed. It can be empty string."); json.add(pn.getPlatform(), pn.toJSON());
}
}
return json;
} public static class Builder {
private Object alert;
private Set<PlatformNotification> builder; public Builder setAlert(Object alert) {
this.alert = alert;
return this;
} public Builder addPlatformNotification(PlatformNotification notification) {
if (null == builder) {
builder = new HashSet<PlatformNotification>();
}
builder.add(notification);
return this;
} public Notification build() {
Preconditions.checkArgument(! (null == builder && null == alert),
"No notification payload is set.");
return new Notification(alert, builder);
}
}
}
当时使用时,感觉这种设计在使用时挺方便的,尤其是对参数的注入,可能构造一个Natification类所使用的代码有点长,但是对参数的使用十分明了。后来才知道这是Builder设计模式,当构造器需多个参数时,可显著改善可读性。根据此代码,自己也仿照写了相应的代码实现。
package com.startup.code.designmode.builder; public class Person { private Name name; private Address address; private Person(Builder builder) {
this.name = builder.name;
this.address = builder.address;
} @Override
public String toString() {
return this.name + "--" + this.address;
} static class Builder{ private Name name; private Address address; public Builder name(Name name) {
this.name = name;
return this;
} public Builder address(Address address) {
this.address = address;
return this;
} public Person build() {
return new Person(this);
}
}
}
person类
package com.startup.code.designmode.builder; public class Name { private String firstName; // 姓
private String lastName; // 名
private String nickName; // 昵称
private String usedName; // 曾用名 @Override
public String toString() {
return "firstName:" + this.firstName + ",lastName:" + this.lastName + ",nickName:" + this.nickName + ",userdName:" + this.usedName;
} private Name(Builder builder) {
this.firstName = builder.firstName;
this.lastName = builder.lastName;
this.nickName = builder.nickName;
this.usedName = builder.usedName;
} /**
* Name的内部构造类
* @author chenq
*
*/
static class Builder {
private String firstName;
private String lastName;
private String nickName;
private String usedName; public Builder firstName(String firstName) {
this.firstName = firstName;
return this;
} public Builder lastName(String lastName) {
this.lastName = lastName;
return this;
} public Builder nickName(String nickName) {
this.nickName = nickName;
return this;
} public Builder usedName(String usedName) {
this.usedName = usedName;
return this;
} public Name build() {
return new Name(this);
}
}
}
Name类
package com.startup.code.designmode.builder; public class Address { private String province; // 省
private String city; // 市
private String district; // 区县 private Address(Builder builder) {
this.province = builder.province;
this.city = builder.city;
this.district = builder.district;
} @Override
public String toString() {
return "province:" + this.province + ",city:" + this.city + ",district:" + this.district;
} /**
* Address的内部构造类
* @author chenq
*
*/
static class Builder {
private String province;
private String city;
private String district; public Builder province(String province) {
this.province = province;
return this;
} public Builder city(String city) {
this.city = city;
return this;
} public Builder district(String district) {
this.district = district;
return this;
} public Address build() {
return new Address(this);
}
}
}
Address
测试类
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);
} }
输出:
aaarticlea/png;base64,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" alt="" />
Builder设计模式--改善构造器多个参数时可显著改善可读性的更多相关文章
- Item 2---遇到构造器具有多个参数时,要考虑用构建器;Builder模式
问题,面对这种一个构造器具备多个参数的问题,现有的做法是使用重叠构造器的方式,该方式存在的问题: public class NutritionFacts { private final int ser ...
- Java调用FFmpeg进行视频处理及Builder设计模式的应用
1.FFmpeg是什么 FFmpeg(https://www.ffmpeg.org)是一套可以用来记录.转换数字音频.视频,并能将其转化为流的开源计算机程序.它用来干吗呢?视频采集.视频格式转化.视频 ...
- C#创建IIS站点及相应的应用程序池,支持IIS6.0+Windows Server 2003. 使用Builder设计模式
测试项目结构: PS:IIS6UtilsBuilder, IIS7UtilsBuilder,IISUtilsBuilder以及IISDirector为Builder设计模式实现的核心代码.Progra ...
- webapi 控制器接收POST参数时必须以对象的方式接收
webapi 控制器接收POST参数时必须以对象的方式接收
- servlet获取参数时,request.getParameter("id")参数获取失败
servlet获取参数时,request.getParameter("id")参数获取失败,这里的参数是“index”里面href中的参数 要注意,取不到值,是不是要取的参数有没有 ...
- js页面传参数时,参数值包含特殊字符的处理
js页面传参数时,参数值包含特殊字符应该怎么处理,解决方法就是利用js的escape函数,这个函数在解决中文乱码等方面应用的比较广泛.推荐使用. 工作中遇到的小问题,一个页面中通过window.sho ...
- SpringMVC中使用bean来接收form表单提交的参数时的注意点
这是前辈们对于SpringMVC接收表单数据记录下来的总结经验: SpringMVC接收页面表单参数 springmvc请求参数获取的几种方法 下面是我自己在使用时发现的,前辈们没有记录的细节和注意点 ...
- 使用Spring mvc接收整个url地址及参数时注意事项
使用Spring mvc接收整个url地址及参数时注意事项:url= http://baidu?oid=9525c1f2b2cd45019b30a37bead6ebbb&td=2015-08- ...
- 【Java学习笔记之二十七】Java8中传多个参数时的方法
java中传参数时,在类型后面跟"..."的使用: public static void main(String[] args){ testStringA ...
随机推荐
- 【线段树】【P2572】【SCOI2010】序列操作
Description lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要么是1,现在对于这个序列有五种变换操作和询问操作: 0 a b 把[a, b]区间内的所有数全变成0 ...
- SAS8.1安装步骤(附图)
安装前应当把系统时间更改到一九九几年. 1.在解压后的文件夹里找到 setup .exe 双击 开始安装 2.单击SAS System Setup 3.点击Next 4.选择 complete 并单击 ...
- VS2010中使用Github进行版本控制【补充】
http://blog.csdn.net/softwave/article/details/8499264 前面我在文章<VS2010结合Github进行版本控制>中介绍了VS 2010中 ...
- centos 前端环境搭建
Node.js 安装 wget 下载安装 yum -y install gcc make gcc-c++ openssl-devel wget node v6.11.0 下载 wget https:/ ...
- Windows下的包管理器Chocolatey
参考文档: https://www.jianshu.com/p/831aa4a280e7 https://www.jianshu.com/p/abaa0e8c261f
- cc1: warnings being treated as errors解决办法
安装GDB时出现cc1: warnings being treated as errors Edit the Makefile and delete this line:WERROR_CFLAGS = ...
- @PathParam 和 @QueryParam
今天调试一个上传功能,客户端手持机发送数据,在URL中附加一个参数,后台用@PathParam接收,但是报错,无法获取这个参数. url:http://192.168.1.3/web1_service ...
- System Administrator(构造,图论)
System Administrator time limit per test 2 seconds memory limit per test 256 megabytes input standar ...
- 在vm上面安装Linux系统
1 在vm上面安装Linux系统 1 以管理员的身份运行VMware: 点击VM图标然后右键属性 ,点兼容性 ---特权 等级 选择 以管理员的身份运行此软件 2 . 添加一个虚 ...
- java多线程机制1(线程创建的两种方式)
进程:正在运行的程序.(即程序在内存中开辟了一片空间) 线程:是进程的执行单元. 一个进程至少包含了一个多个线程. 多线程是不是可以提高效率:多线程可以合理的利用系统的资源,提高效率是相对的.因为cp ...