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

  1. Item 2---遇到构造器具有多个参数时,要考虑用构建器;Builder模式

    问题,面对这种一个构造器具备多个参数的问题,现有的做法是使用重叠构造器的方式,该方式存在的问题: public class NutritionFacts { private final int ser ...

  2. Java调用FFmpeg进行视频处理及Builder设计模式的应用

    1.FFmpeg是什么 FFmpeg(https://www.ffmpeg.org)是一套可以用来记录.转换数字音频.视频,并能将其转化为流的开源计算机程序.它用来干吗呢?视频采集.视频格式转化.视频 ...

  3. C#创建IIS站点及相应的应用程序池,支持IIS6.0+Windows Server 2003. 使用Builder设计模式

    测试项目结构: PS:IIS6UtilsBuilder, IIS7UtilsBuilder,IISUtilsBuilder以及IISDirector为Builder设计模式实现的核心代码.Progra ...

  4. webapi 控制器接收POST参数时必须以对象的方式接收

    webapi    控制器接收POST参数时必须以对象的方式接收

  5. servlet获取参数时,request.getParameter("id")参数获取失败

    servlet获取参数时,request.getParameter("id")参数获取失败,这里的参数是“index”里面href中的参数 要注意,取不到值,是不是要取的参数有没有 ...

  6. js页面传参数时,参数值包含特殊字符的处理

    js页面传参数时,参数值包含特殊字符应该怎么处理,解决方法就是利用js的escape函数,这个函数在解决中文乱码等方面应用的比较广泛.推荐使用. 工作中遇到的小问题,一个页面中通过window.sho ...

  7. SpringMVC中使用bean来接收form表单提交的参数时的注意点

    这是前辈们对于SpringMVC接收表单数据记录下来的总结经验: SpringMVC接收页面表单参数 springmvc请求参数获取的几种方法 下面是我自己在使用时发现的,前辈们没有记录的细节和注意点 ...

  8. 使用Spring mvc接收整个url地址及参数时注意事项

    使用Spring mvc接收整个url地址及参数时注意事项:url= http://baidu?oid=9525c1f2b2cd45019b30a37bead6ebbb&td=2015-08- ...

  9. 【Java学习笔记之二十七】Java8中传多个参数时的方法

    java中传参数时,在类型后面跟"..."的使用:        public static void main(String[] args){       testStringA ...

随机推荐

  1. JavaScript中“&&”和“||”操作符的意义,深入理解和使用场景

     一.概念 与其他语言不同,在js中,逻辑运算符可以返回任何类型的数据,不仅仅是true和false. &&和||的返回值是两个操作数的其中一个.即a&&b或者a||b ...

  2. PD模型创建完获取生成表脚本

    1.双击表名,弹出属性对话框-->General----> Owner 表名前缀,如XX.SYS_TABLE  最好去掉 2.Preview 复制里面的脚本到数据库执行下即可

  3. unity3D 涂涂乐使用shader实现上色效果

    unity3D 涂涂乐使用shader实现上色效果 之前我博文里面发过一个简单的通过截图方式来实现的模型上色方法,但是那个方法不合适商用,因为你需要对的很准确才可以把贴图完美截取下来,只要你手抖了一下 ...

  4. laravel添加日常备份任务

    app/Console/Command/MySqlDump.php <?php namespace App\Console\Commands; use Illuminate\Console\Co ...

  5. C ------ static 关键字的作用

    首先要理解生存周期与作用域的区别: 生存周期: 变量从定义到销毁的时间范围.存放在全局数据区的变量的生存周期存在于整个程序运行期间,而存放在栈中的数据则随着函数等的作用域结束导致出栈而销毁,除了静态变 ...

  6. 转:Unable to execute dex: Multiple dex files define 解决方法

    转自:http://blog.csdn.net/mxlxiao7/article/details/8978930 问题发生概述: 程序编译正常,在用Eclipse调试执行时,报错Unable to e ...

  7. OpenCV---对象测量

    一:获取图像的外接矩形boundingRect和几何距moments import cv2 as cv import numpy as np def measure_object(image): gr ...

  8. tomcat启动 报org.apache.catalina.LifecycleException异常

    java 服务器 tomcat启动 报org.apache.catalina.LifecycleException异常 异常代码如下: [2018-05-10 04:45:08,856] Artifa ...

  9. UITableView .grouped 类型去除顶部间距

    在设置 UITableView 的 style 为 .grouped 类型的时候,发现第一个 cell 的顶部存在大段的间距,而改为 .plain 类型则没有这个间距,效果如下: 设置了 conten ...

  10. Debian9(8)下python3和python2同时安装如何使用pip

    在bash下Python会调用python2.x python3会调用python3.x 如果使用pip install命令安装模块会安装python2的模块. 而python3的pip命令使用的是p ...