builder模式的新学习

静态工厂和构造器有个共同的局限性:他们不能很好的扩展到大量的可选参数。大多数产品在牧歌可选与中都会有非零的值

对于这种类,应该使用哪种构造器或者静态方法来进行编写?程序员一般习惯采用重叠构造器(telescoping constructor)模式。在这种模式下,你可以第一个只有必要参数的构造器,第二个构造器有一个可选参数,第三个有两个可选参数,以此类推,最后一个构造器包含所有的可选参数。

public class NutritionFacts {
private final int servingSize; //required
private final int servings; //required
private final int calories; //optional
private final int fat; //optional
private final int sodium; //optional
private final int carbohydrate; //optional public NutritionFacts(int servingSize,int servings){
this(servingSize,servings,0);
}
public NutritionFacts(int servingSize,int servings,int calories){
this(servingSize,servings,calories,0);
}
public NutritionFacts(int servingSize,int servings,int calories,int fat){
this(servingSize,servings,calories,fat,0);
}
public NutritionFacts(int servingSize,int servings,int calories,int fat,int sodium){
this(servingSize,servings,calories,fat,sodium,0);
}
public NutritionFacts(int servingSize,int servings,int calories,int fat,int sodium,int carbohydrate){
this.servingSize = servingSize;
this.servings = servings;
this.calories = calories;
this.fat = fat;
this.sodium = sodium;
this.carbohydrate = carbohydrate;
}
}

当我们想要穿件实例的时候,就利用参数列表最短的构造器,但是该列表包含了要设置的所有参数:

NutritionFacts cocaCloa = new NutritionFacts(240,8,100,0,35,27);

这个构造器通常需要许多你本不想设置的参数,但是不能不为它传递值。在这个例子中,我们给fat传递了一个值为0。如果“仅仅”只有6个参数,看起来并不算太早,问题是随着参数数目的增加,它很快就会失去控制。

使用JavaBean模式,也能够代替这种问题。遗憾的是在一定的情况下,我们需要额外的努力来保证它的安全性。

幸运的是,还有新的替代方法,既能够保证向重叠构造器模式那样安全,也能够保证像JavaBean模式的那么好的可读性。这就是Builder模式的一种形式。不直接生成想要的对象。然后客户端利用所有必要的参数调用构造器(或者静态工厂),得到一个builder对象。然后客户端在builder对象上调用类似于setting的方法,来设置每个相关的可选参数。最后,客户端调用午餐的build方法来生成不可变的对象。这个builder是他构建的类的静态成员类。

//Builder Pattern
public class NutritionFacts{
private final int servingSize; //required
private final int servings; //required
private final int calories; //optional
private final int fat; //optional
private final int sodium; //optional
private final int carbohydrate; //optional public static class Builder{
private final int servingSize; //required
private final int servings; //required
private int calories; //optional
private int fat; //optional
private int sodium; //optional
private int carbohydrate; //optional public Builder(int servingSize,int servings){
this.servingSize = servingSize;
this.servings = servings;
}
public Builder calories(int val){
this.calories = val;
return this;
}
public Builder fat(int val){
this.fat = val;
return this;
}
public Builder sodium(int val){
this.sodium = val;
return this;
}
public Builder carbohydrate(int val){
this.carbohydrate = val;
return this;
}
public NutritionFacts build(){
return new NutritionFacts(this);
}
}
private NutritionFacts(Builder builder){
this.servingSize = builder.servingSize;
this.servings = builder.servings;
this.calories = builder.calories;
this.fat = builder.fat;
this.sodium = builder.sodium;
this.carbohydrate = builder.carbohydrate;
}
}

注意NutrtionFacts是不可变的,所有的默认参数都是单独放在一个地方。builder的setter方法返回builder本身,以便可以把调用连接起来。

NutritionFacts nutritionFacts =
new NutritionFacts.Builder(240, 8)
.calories(100)
.sodium(35)
.carbohydrate(27)
.build();

这样的调用客户端代码很容易编写,更为重要的是易于阅读。

build方法可以检验这些约束条件。将参数从builder拷贝到对象中之后,并在对象域而不是builder域中对他们进行检验。如果违反了约束条件,build方法就应该抛出IllegalStateException。

Builder 模式自身的不足。为了创建对象,必须先创建它的构造器。虽然创建构造器的开销在实践中可能并不明显,但是在某些十分注重性能的情况下,可能就成问题了。

Builder 模式还比重叠构造器模式更加冗长,因此它只能在有很多参数的时候才使用。比如4个或者更多的参数。但是记住,将来你可能添加参数。如果一开始就是用构造器或者静态工厂,等类需要更多的参数时才添加构造器就会无法控制,那些过时的构造器或者静态工厂显得十分的不协调。因此,通常最好一开始就是用构造器。

简而言之,如果类的构造器或者静态工厂中具有多个参数,设计这种类的时,Builder模式就是种不错的选择,特别是当大多数的参数都是可选的时候。

builder模式的新学习的更多相关文章

  1. Android 开发学习进程0.30 builder模式创建popwindow

    builder模式创建自定义popwindow builder设计模式 将一个复杂的对象构建与它的表示分离,简化代码的使用方式.当对象有多个参数或多个零件同时初始化方法同时初始化方法有默认值时,采用此 ...

  2. 设计模式-----Builder模式

    前言 近日,看到Myabtis中组件中SqlSessionFactory由SqlSessionFactoryBuilder().build()生成时,且采用Builder模式,遂记录学习之. SqlS ...

  3. Java Builder 模式,你搞懂了么?

    加油.png 前言:最近闲来无事的时候想着看看一些平常用的三方库源码,没想到看了之后才知道直接撸源码好伤身体,一般设计优秀的开源库都会涉及很多的设计模式,就比如 android 开发使用频繁的 okH ...

  4. Java Builder 模式,你搞明白了么?

    Builder 模式定义 Builder 模式中文叫作建造者模式,又叫生成器模式,它属于对象创建型模式,是将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示.建造者模式是一步一步 ...

  5. Builder模式在Java中的应用

    在设计模式中对Builder模式的定义是用于构建复杂对象的一种模式,所构建的对象往往需要多步初始化或赋值才能完成.那么,在实际的开发过程中,我们哪些地方适合用到Builder模式呢?其中使用Build ...

  6. 创建型模式之Builder模式及实现

    建造者(Builder)模式 GOF给出的定义为:建造者模式是将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. 应用场景 使用建造者模式是为了将构建复杂对象的过程和它的部件 ...

  7. Android Builder模式在开发中的应用

    最近在学习图片加载框架Glide的时候,被他精简的写法震惊了.一句话,就可以搞定. Glide.with(mContext) .load(url) .centerCrop() .placeholder ...

  8. Builder模式(建造者模式)

    在设计模式中对Builder模式的定义是用于构建复杂对象的一种模式,所构建的对象往往需要多步初始化或赋值才能完成.那么,在实际的开发过程中,我们哪些地方适合用到Builder模式呢?其中使用Build ...

  9. Builder模式在Java中的应用(转)

    在设计模式中对Builder模式的定义是用于构建复杂对象的一种模式,所构建的对象往往需要多步初始化或赋值才能完成.那么,在实际的开发过程中,我们哪些地方适合用到Builder模式呢?其中使用Build ...

随机推荐

  1. Cocos2d-JS 项目接入 触控广告平台(基于anysdk2.0.2)

    本文以Cocos2d-JS项目作为示例,讲解如何集成AnySDK-JS. 一.如何创建项目我就省略了,直接进入主题. 1.1 首先,我需要下载anysdk框架包,下载地址:http://www.any ...

  2. Hibernate总结(转)

    原文:http://blog.csdn.net/yuebinghaoyuan/article/details/7300599 那我们看一下hibernate中整体的内容: 我们一一介绍其中的内容. H ...

  3. TCP/IP,HTTP,Socket初识

    在大学时候学过网络通信这一块,奈何已经还给老师,苍天饶过谁,该拾起来看看学学的还是要学,先简单了解了下这方面的知识,后续会继续通过看书来充实这方面的知识. 手机能够联网是手机底层实现了TCP/IP协议 ...

  4. 用HTML5 Canvas为Web图形创建特效

    HTML5 Canvas 将使用像素在屏幕上绘制图形图像. 本节演示了五种用于操作像素以创建摄影特效的 Canvas 技术. 您可使用这些技术来生成独具特色的图像,为您的网站.博客.视频游戏画面.广告 ...

  5. BZOJ 1619 [Usaco2008 Nov]Guarding the Farm 保卫牧场:dfs【灌水】

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1619 题意: 给你一个n*m的地形图,位置(x,y)的海拔为h[x][y]. 一个山顶的定 ...

  6. druid.io 海量实时OLAP数据仓库 (翻译+总结) (1)——分析框架如hive或者redshift(MPPDB)、ES等

    介绍 我是NDPmedia公司的大数据OLAP的资深高级工程师, 专注于OLAP领域, 现将一个成熟的可靠的高性能的海量实时OLAP数据仓库介绍给大家: druid.io NDPmedia在2014年 ...

  7. nltk: Tokenizing text into sentences

    安装 nltk pip install nltk 下载nltk_data 方法一: 通过客户端下载 import nltk nltk.download() 出现如下客户端,选择所需的包下载.(但由于网 ...

  8. 初始化cache_dir(squid)

    sed -i '/adjustFactor/d' /CNCLog/exactTraffic/conf/localTraffic.cfgecho "adjustFactor = '-0.67 ...

  9. Update 出现在的问题

    报错提示:之前的操作没有完成,运行deanup被打断,请先执行Cleanup方法. 正常右键点击Cleanup,如果只让默认值勾选,可能还是会报这个错.所以正确操作如下: 全部选中再点击OK,这样就可 ...

  10. XML 解析中 SelectSingleNode 与 SelectNodes 使用通配符介绍

    俺是 XML XPath的新手,最近因为项目需要,研究了一下基本的两个函数 SelectSingleNode和SelectNodes 是如何实用通配符的,分享以下基本经验: 假设有段XML 如下所示: ...