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. input光标位置

    兼容谷歌火狐-input光标位置 input框在没有添加任何效果的情况下,输入文字后光标始终在最后的位置,谷歌||火狐效果一样 但是在给input加入点击事件后 谷歌:input框插入文字后,光标会自 ...

  2. select监听多个client -- linux函数

    使用select函数能够以非堵塞的方式和多个socket通信.程序仅仅是演示select函数的使用,功能很easy,即使某个连接关闭以后也不会改动当前连接数.连接数达到最大值后会终止程序. 1. 程序 ...

  3. 阿里妈妈-RAP项目的实践(1)

    在同事的推荐下,去了解了一下http://thx.github.io/RAP/study.html#,它是发现在前后端分离开发的神器 下面我们来简单上一组代码,来简单了解一下rap <!DOCT ...

  4. 自定义fragmentlayout

    一.抽取视图文件,实例化需要在xml文件中 先上效果图: 1.  编写 xml布局文件 <?xml version="1.0" encoding="utf-8&qu ...

  5. java中设计模式详解

    一.设计模式的分类 总体来说设计模式分为三大类: (1)创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. (2)结构型模式,共七种:适配器模式.装饰器模式.代理模式.外 ...

  6. Double.valueOf()与Double.parseDouble()两者的区别

    写代码用到这两个方法,不知道有什么区别,看一下源码: Double.parseDouble(String str) public static double parseDouble(String s) ...

  7. kernel中对文件的读写【学习笔记】【原创】

    /*1. 头文件 */ #include <linux/init.h> #include <linux/module.h> #include <linux/modulep ...

  8. Oracle中视图和同义词的区别

    视图和同义词分别都是数据库中的对象名称,它们都不对应实际的数据存储,都依赖其他对象的存在而存在.视图:视图可以被看成是虚拟表或存储查询.除非是索引视图,否则视图的数据不会作为非重复对象存储在数据库中. ...

  9. C语言中的排序算法--冒泡排序,选择排序,希尔排序

    冒泡排序(Bubble Sort,台湾译为:泡沫排序或气泡排序)是一种简单的排序算法.它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没 ...

  10. 第三篇:python基础之数据类型与变量

    阅读目录 一.变量 二.数据类型 2.1 什么是数据类型及数据类型分类 2.2 标准数据类型: 2.2.1 数字 2.2.1.1 整型: 2.2.1.2 长整型long: 2.2.1.3 布尔bool ...