设计模式之Builder模式

本文介绍了一种解决Java类构造方法中大量参数问题的方法——Builder模式。通过使用内部Builder类,可以灵活地设定必填和选填参数,提高代码的可读性和可维护性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

情景需要:

假设有这样一个Human类,要构造一个Human对象必须传递6个参数,其中前3个是必须的,后3个是可选的:

  1. classHuman{
  2. //requiredparameters
  3. privatefinalStringname;
  4. privatefinalStringgender;
  5. privatefinalintage;
  6. //optionalparameters
  7. privatefinalintheight;
  8. privatefinalintweight;
  9. privatefinalStringcountry;
  10. }

那么,给这个类设计构造方法会是比较头疼的事。

一种方案是,我们可以设计一个有6个参数的构造方法,分别给name, gender, height, weight, country赋值,其中后3个值可以有缺省值。如:

  1. publicHuman(Stringname,Stringgender,intage,intheight=180,intweight=50,Stringcountry="China"){
  2. //......
  3. }

然而这样设计有一个不足之处,那就是后3个参数虽然有缺省值,但参数的顺序是固定的,不能变的,如果用户在传参的时候把顺序搞错了,就会产生错误。而且如果参数类型相同的话,编译器也不会报错。为了弥补这样的不足,我们可以重载构造方法,如:

  1. publicHuman(Stringname,Stringgender,intage){}
  2. publicHuman(intheight){}//不能构成重载
  3. publicHuman(intweight){}//不能构造重载
  4. publicHuman(Stringcountry){}

这样虽然解决了参数顺序的问题,但如果这个类的可选参数有不只3个,比如有6个,10个,20个的话,那么就要设计大量的重载的方法,非常费事。而且上面的代码还存在一个问题,那就是第2个和第3个方法根本无法构成重载。也就是说,当可选参数的参数类型有重复的时候,上面的设计方法就不可行了。


这时候我们就可以采用 Builder模式 来解决这样问题。


Builder模式

我们可以在Human的内部定义一个静态的内部类Builder,通过这个类来完成对参数的赋值工作,如:
class Human {
	// required parameters
	private final String name;
	private final String male;
	private final int age;

	// optional parameters
	private final int height;
	private final int weight;
	private final String country;

	// builder class
	public static class Builder {
		// required parameters
		private final String name;
		private final String male;
		private final int age;

		// optional parameters
		private int height = 0;
		private int weight = 0;
		private String country = "none";

		public Builder(String name, String male, int age) {
			this.name = name;
			this.male = male;
			this.age = age;
		}

		public Builder setHeight(int h) {
			this.height = h;
			return this;
		}
		public Builder setWeight(int w) {
			this.weight = w;
			return this;
		}
		public Builder setCountry(String c) {
			this.country = c;
			return this;
		}

		public Human build() {
			return new Human(this);
		}
	}
}


然后为Human提供一个私有的构造方法,以Builder对象作为其形参,在此构造方法中完成参数的赋值:
  1. privateHuman(Builderb){
  2. name=b.name;
  3. gender=b.gender;
  4. age=b.age;
  5. height=b.height;
  6. weight=b.weight;
  7. country=b.country;
  8. }


这样一来,用户 在使用Human 这个类的时候,就可能以如下的方式来构造Human对象:

  1. Humanhm=newHuman.Builder("bruce","male",20)//设置必须参数
  2. .setCountry("China")//设置可选参数
  3. .setWeight(50)//设置可选参数
  4. .build();//构造对象

显然,Human类的使用者在创建其对象时所写的代码就变得简单明了多了。


因此,当一个类的构造方法必须传递大量参数的时候,我们可以考虑使用Builder模式来构造此类。当应用程序对性能要求不是很高时,Builder模式是处理此类情形的最好方案。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值