2.2 使用builder替代多参数构造函数

如果构造函数参数超过4个,可以考虑使用builder创建对象。

 

如下,MultiConstructorShoe提供了多个构造函数,以避免使用包含最多参数的构造函数:

 

package com.bingo.practice.effective.two.two;

public class MultiConstructorShoe {
	//鞋的名称
	private String name;
	//鞋的大小
	private int size;
	//鞋的颜色
	private int color;
	//鞋的类型,如男鞋、女鞋,童鞋
	private int sex;
	
	public MultiConstructorShoe(String name,int size){
		this(name,size,0,0);
	}
	
	public MultiConstructorShoe(String name,int size,int color){
		this(name, size,color,0);
	}
	
	public MultiConstructorShoe(String name,int size,int color,int sex){
		this.name=name;
		this.size=size;
		this.color=color;
		this.sex=sex;
	}

	public String getName() {
		return name;
	}

	public int getSize() {
		return size;
	}

	public int getColor() {
		return color;
	}

	public int getSex() {
		return sex;
	}
}

 

 

可以使用JavaBean形式,使用setter分别设置属性值。此方式的缺点在于无法保证对象被使用前,所有必需的属性值都已设置。比如保证name,size属性都已被设置后才使用此对象

package com.bingo.practice.effective.two.two;

public class JavaBeanShoe {
	//鞋的名称
	private String name;
	//鞋的大小
	private int size;
	//鞋的颜色
	private int color;
	//鞋的类型,如男鞋、女鞋,童鞋
	private int sex;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getSize() {
		return size;
	}

	public void setSize(int size) {
		this.size = size;
	}

	public int getColor() {
		return color;
	}

	public void setColor(int color) {
		this.color = color;
	}

	public int getSex() {
		return sex;
	}

	public void setSex(int sex) {
		this.sex = sex;
	}
	
	
}

 

 

以下是使用Builder创建对象,此方法的优点在于:1.避免使用包含过多参数的构造函数 2.保证所有必需属性设置完成后才返回所创建的对象 3.可使用链式语法设置属性

package com.bingo.practice.effective.two.two;

public class BuilderShoe {
	//鞋的名称
	private String name;
	//鞋的大小
	private int size;
	//鞋的颜色
	private int color;
	//鞋的类型,如男鞋、女鞋,童鞋
	private int sex;

	public String getName() {
		return name;
	}

	public int getSize() {
		return size;
	}

	public int getColor() {
		return color;
	}

	public int getSex() {
		return sex;
	}
	
	public static class Builder{
		private String name;
		private int size;
		private int color;
		private int sex;		
		
		public Builder(String name,int size){
			this.name=name;
			this.size=size;
		}
		
		public Builder name(String name){
			//可添加校验逻辑
			this.name=name;
			return this;
		}
		public Builder size(int size){
			this.size=size;
			return this;
		}
		public Builder color(int color){
			this.color=color;
			return this;
		}
		public Builder sex(int sex){
			this.sex=sex;
			return this;
		}
		
		public BuilderShoe build(){
			//可添加校验逻辑
			BuilderShoe shoe=new BuilderShoe();
			shoe.name=this.name;
			shoe.size=this.size;
			shoe.color=this.color;
			shoe.sex=this.sex;
			return shoe;
		}
	}
}

 

以上3个类测试代码如下,使用builder方式的确更优美:

package com.bingo.practice.effective.two.two;

import org.testng.Assert;
import org.testng.annotations.Test;

public class BuilderTest {
	@Test
	public void testMultiConstructorShoe(){
		MultiConstructorShoe shoe=new MultiConstructorShoe("bingo", 42,0,0);
		Assert.assertEquals(shoe.getName(), "bingo");
	}
	
	@Test
	public void testJavaBeanShoe(){
		JavaBeanShoe shoe=new JavaBeanShoe();
		shoe.setName("bingo");
		shoe.setSize(42);
		shoe.setColor(0);
		shoe.setSex(0);
		Assert.assertEquals(shoe.getName(), "bingo");
	}
	
	@Test
	public void testBuilderShoe(){
		BuilderShoe shoe=new BuilderShoe.Builder("bingo", 42).color(0).sex(0).build();
		Assert.assertEquals(shoe.getName(), "bingo");
	}
}

 

 

builder可以配合工厂设计模式一起使用(原书指配合抽象工厂设计模式使用)。假设我们需要生产多种不同类型的鞋,每种鞋的制作工艺都不同。因此我们可以声明一个Builder接口,其每个实现类负责生产一种鞋。接口声明如下:

public interface Builder<T extends Shoe> {
	T build();
}

 

接着声明工厂接口,如下。其中ShoeFactory的createShoe(builder)方法会调用传入的builder生产鞋:

public interface ShoeFactory<T extends Shoe> {
	T createShoe(Builder<T> builder);
}

 

假设每种鞋都需要使用相同的Logo,并且需要设置生产日期,那么可以在工厂实现类里进行这些操作,如下:

public  class BaseShoeFactory<T extends Shoe> implements ShoeFactory<T>{

	public T createShoe(Builder<T> builder) {
		T shoe=builder.build();
		shoe.setLogo("MyShoeLogo");
		shoe.setCreationDate(new Date());
		return null;
	}
	
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值