effective java笔记(一) —— 构造器实现之builder模式

当一个类中有大量的构造参数时,静态方法和构造器已经不能满足对象的实例化,那么我们将考虑构建器。

构建器模式:1、重叠构造器模式
            2、javaBeans模式(自己常用的一种)
        3、builder模式

重叠构造器模式:这种模式下,提供第一个只有必要参数的构造器,第二个构造器有一个可选参数,第三个有两个可选参数,以此类推,最后一个构造器包含所有可选参数。

javaBeans模式:调用在各分无参构造器创建对象,然后调用setter方法来设置每个必要的参数,以及每个相关的可选参数。

builder模式:builder像个构造器一样,可以对其参数强加约束条件。build方法可以检验这些约束条件。将参数从builder拷贝到对象中之后,并在对象域而不是builder域中对它们进行检验,这一点很重要。如果违反了人格约束条件,build方法就应该抛出IllegalStateException。异常的详细信息应该显示出违反哪个约束条件。

从上不难看出:重叠构造器模式在参数很多的情况下,客户端代码会很难写,并且难以阅读。
          javaBeans模式因为构造过程分到了几个调用中,在构造过程中javaBean可能处于不一致的状态,类无法仅仅通过校验构造参数的有效性来保证一致性。这样程序员需要付出额外的努力来确保它的线程安全

builder模式技能保证像重叠构造器模式那样的安全性,也能保证像javaBeans模式那么好的可读性。
 

下面直接上代码:

 

package com.yy.test;
/**
 * builder模式
 * @author admin
 *
 */
public class NutritionFacts {
	private final int servingSize;
	private final int servings;
	private final int calories;
	private final int fat;
	private final int sodium;
	private final int carbohydrate;

	public static class Builder{
		//必须注入的参数,可不用初始化
		private final int servingSize;
		private final int servings;
		
		//可选择注入的参数
		private int calories = 0;
		private int fat = 0;
		private int sodium = 0;
		private int carbohydrate = 0;
		
		//builder类构造方法
		public Builder(int servingSize,int servings){
			this.servingSize = servingSize;
			this.servings = servings;
		}
		
		public Builder calories(int val){
			calories = val;
			return this;
		}
		public Builder carbohydrate(int val){
			carbohydrate = val;
			return this;
		}
		public Builder sodium(int val){
			sodium = val;
			return this;
		}
		
		//将当前对象传入外部内的私有构造方法中
		public NutritionFacts build(){
			return new NutritionFacts(this);
		}
	}
	
	//私有构造方法
	private NutritionFacts(Builder builder){
		servingSize = builder.servingSize;
		servings = builder.servings;
		calories = builder.calories;
		fat = builder.fat;
		sodium = builder.sodium;
		carbohydrate = builder.carbohydrate;
	}
	
	@Override
	public String toString() {
		return "NutritionFacts [calories=" + calories + ", carbohydrate="
				+ carbohydrate + ", fat=" + fat + ", servingSize="
				+ servingSize + ", servings=" + servings + ", sodium=" + sodium
				+ "]";
	}
	
	public static void main(String[] args) {
		NutritionFacts nf = new NutritionFacts.Builder(8, 20).calories(2).sodium(27).build();
		System.out.println(nf);
	}
}

 

当Builder中传入一个无效参数时,直接抛出相应异常,不会等到调用build方法。

 

builder模式十分灵活,可以利用单个builder构建多个对象。builder的参数可以在创建对象期间进行调整,也可以随着不同的对象而改变。

 

   虽然基本都是书上有点,但是也要学着自己理一遍。慢慢的会从借鉴变为运用的。

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值