`
coolxing
  • 浏览: 874217 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
9a45b66b-c585-3a35-8680-2e466b75e3f8
Java Concurre...
浏览量:97291
社区版块
存档分类
最新评论

使用Builder模式创建对象

阅读更多

[coolxing按: 转载请注明作者和出处, 如有谬误, 欢迎在评论中指正.]

创建对象的方法很多, 常见的有构造函数, 静态工厂方法, 工厂方法等. 

以上三种方法不适合创建需要提供多个参数的对象, 而其中某些参数是可选的场景.

考虑一个Person类:

public class Person {
	// 必须的参数
	private int id;
	private String name;
	private int age;
	
	// 可选参数
	private String city;
	private String hoby;
	private String job;
	private String sex;
}
  

如果给这个Person类提供合适的构造函数, 应该怎么做呢?

也许我们可以提供多个构造函数, 每个构造函数都包含必须的参数, 以及0个或多个可选参数. 例如:

public Person(int pid, String name, int age) {
		this.id = pid;
		this.name = name;
		this.age = age;
}
	
public Person(int id, String name, int age, String city) {
		this.id = id;
		this.name = name;
		this.age = age;
		this.city = city;
}
	
public Person(int id, String name, int age, String city, String hoby) {
		super();
		this.id = id;
		this.name = name;
		this.age = age;
		this.city = city;
		this.hoby = hoby;
}
	
public Person(int id, String name, int age, String city, String hoby, String job) {
		this.id = id;
		this.name = name;
		this.age = age;
		this.city = city;
		this.hoby = hoby;
		this.job = job;
}

public Person(int id, String name, int age, String city, String hoby, String job, String sex) {
		this.id = id;
		this.name = name;
		this.age = age;
		this.city = city;
		this.hoby = hoby;
		this.job = job;
		this.sex = sex;
}

这种方法至少存在这样的问题:

1. 如果需要创建一个只指定city和sex的Person对象, 我们就必须调用public Person(int id, String name, int age, String city, String hoby, String job, String sex)方法, 然后将hoby, job都赋值为空字符串. 这是让人疑惑的, 也是丑陋的.

2. 这样的代码难以阅读, 而且臃肿不堪, 不具备良好的可伸缩性.

 

当然我们可以同时提供属性的getter和setter方法, 然后只保留Person(int pid, String name, int age)一个构造函数.

如此的话, 我们先通过Person(int pid, String name, int age)方法创建Person对象, 然后调用需要的setter方法给可选参数赋值.

这是不错的解决方法, 但是创建对象被分成了几个步骤, 这会带来问题: 如果一不小心可能会让将尚未完全创建的Person对象泄露出去--结果是严重的. 

 

Builder设计模式就非常适合这样的场景:

public class Person {
	// 必须的参数
	private int id;
	private String name;
	private int age;

	// 可选参数
	private String city;
	private String hoby;
	private String job;
	private String sex;

	// 私有构造函数
	private Person(Builder builder) {
		this.id = builder.id;
		this.name = builder.name;
		this.age = builder.age;
		this.city = builder.city;
		this.hoby = builder.hoby;
		this.job = builder.job;
		this.sex = builder.sex;
	}

	public static class Builder {
		// 必须的参数
		private int id;
		private String name;
		private int age;

		// 可选参数
		private String city;
		private String hoby;
		private String job;
		private String sex;

		// 设置必须的参数
		public Builder(int id, String name, int age) {
			this.id = id;
			this.name = name;
			this.age = age;
		}
		
		// 设置可选参数, 返回Builder对象可以让调用者使用级联
		public Builder setCity(String city) {
			this.city = city;
			return this;
		}
		
		public Builder setHoby(String hoby) {
			this.hoby = hoby;
			return this;
		}
		
		public Builder setJob (String job) {
			this.job = job;
			return this;
		}
		
		public Builder setSex(String sex) {
			this.sex = sex;
			return this;
		}
		
		public Person build() {
			return new Person(this);
		}
	}
}

如果需要一个指定city和sex的Person对象, 就可以这样创建:

Person.Builder builder = new Person.Builder(1, "xing", 25);
Person person = builder.setCity("beijing").setSex().build();

在调用build方法完成之前, Person对象都没有被创建, 所以无需担心提前泄露的问题, 而且使用级联的方式使得代码简洁优雅.

 

总结: Builder模式只适合创建对象时需要指定多个可选参数的场景.

 

5
1
分享到:
评论
5 楼 lemon_gogogo 2015-04-29  
抄来抄去有意思么? 《effectivejava》
4 楼 heipacker 2013-10-12  
这个也太复杂了吧,想想就创建一个对象而已 值吗
3 楼 wangchangshuai0010 2012-03-09  
不错的防泄漏方法!
2 楼 coolxing 2012-03-09  
minjie0128 写道
顺便问下,为什么要建个内部类啊

这个Builder是专门用于创建Person对象的, 所以Builder类从属于Person类. 因此使用内部类可以清晰的表述这种从属关系.
使用"静态"内部类则是为了在不存在Person对象时创建Builder对象
1 楼 minjie0128 2012-03-09  
顺便问下,为什么要建个内部类啊

相关推荐

    Java设计模式:Builder模式应用案例[整理].pdf

    // 使用Builder模式创建对象 NutritionFacts nf1 = new NutritionFacts.Builder() .servingSize(20) .servings(100) .build(); NutritionFacts nf2 = new NutritionFacts.Builder() .servingSize(240) ....

    设计模式 创建型模式 Builder模式(建造者)

    这些的算法和步骤是稳定的,而构成这个对象的子对象却经常由于需求改变而发生变化,此时我们可以选择使用Builder模式。尽管Builder模式相当容易让人误解,但我认为这几点应该是不会有错的。因此我个人认为Builder...

    (创建型模式)Builder模式

    Builder模式是一种创建型设计模式,它提供了一种方法来分步骤构建复杂的对象,使得构建过程和表示分离。这种模式在程序开发中常用于构造产品对象,尤其是当对象的构造过程较为复杂时,Builder模式能够帮助我们更好地...

    设计模式-Builder模式demo

    Builder模式是一种创建型设计模式,它提供了一种创建对象的抽象接口,并允许子类按照步骤构建复杂的对象。这种模式将对象的创建过程分离出来,使得同样的构造过程可以创建不同的表示,从而实现对象创建过程的解耦。 ...

    Builder模式

    3. 在产品创建过程中需要使用系统中的其他对象,且这些对象在创建过程中不易获取时,Builder模式可以封装这部分细节,使得创建过程更加清晰和可控。 #### 优点 - **内部表象独立变化**:Builder模式允许产品的内部...

    创建型——Builder模式

    Builder模式是一种创建型设计模式,它提供了一种创建对象的灵活方式,...通过使用Builder模式,我们可以使代码更易读、易维护,并增加创建对象的灵活性。同时,它也是其他设计模式如Prototype和Factory模式的有力补充。

    设计模式-创建者模式(Builder)

    创建者模式(Builder)是软件设计模式中的一种结构型模式,它将一个复杂对象的构造与它的表示分离,使得同样的构建过程可以创建不同的表示。该模式允许用户可以只通过指定复杂对象的类型和内容就可以构建它们,而不...

    设计模式之创建模式Builder

    建造者模式(Builder Pattern)是设计模式中的一种创建型模式,它允许我们分步骤构建复杂的对象,而无需暴露其构造过程。这种模式的核心思想在于将对象的构建与表示分离,使得构建过程和不同表示可以独立变化,提高...

    详解建造者(builder)模式的创建对象使用方式

    详解建造者(builder)模式的创建对象使用方式

    C#面向对象设计模式纵横谈(4):Builder 生成器模式(创建型模式)

    Builder模式是一种创建型设计模式,它提供了一种创建对象的抽象接口,并允许使用不同的实现来控制对象的构造过程。在C#中,Builder模式经常被用于复杂对象的构建,特别是当构建过程需要多个步骤或者需要在不同环境中...

    builder设计模式源码

    1. **Product(产品类)**:这是Builder模式所创建的对象。在这个例子中,Product可能是一个复杂的对象,比如一个软件应用程序或硬件设备的配置。它定义了产品的公共接口,确保所有Builder生成的对象都符合这个接口...

    Builder 模式

    这种模式允许我们通过分离对象的构造过程和表示来创建对象,使得构造过程可以更加灵活,并且能够避免在构造过程中对对象状态的直接修改。Builder模式的核心在于将一个复杂的构建与其表示相分离,使得同样的构建过程...

    BUILDER模式 C++实现

    Builder模式是一种设计模式,它属于创建型模式,主要用于复杂对象的构建。在C++中,Builder模式可以帮助我们分步骤地创建一个复杂的对象,而无需关注这些步骤如何组合在一起。这样可以使得构造过程更加灵活,同时也...

    C#面向对象设计模式纵横谈(4):Builder 生成器模式(创建型模式) (Level 300)

    Builder模式是一种创建型设计模式,它提供了一种创建对象的抽象接口,并允许使用不同的实现来创建复杂的对象。在C#中,Builder模式可以帮助我们在不暴露复杂构造过程的情况下,创建具有多种构建步骤的对象。这种模式...

    【Java 设计模式-源码】Builder 模式:在 Java 中清晰构建自定义对象

    在 Java 开发中,Builder 模式是一种强大的创建型模式,它允许我们逐步构建复杂的对象。本文将详细介绍 Builder 模式的意图、解释、编程示例、适用场景以及实际应用。同时,还将提供示例代码的下载链接,方便读者...

    设计模式之建造者Builder模式

    2. 当创建对象的过程很复杂,或者需要按照特定顺序进行时。 3. 当希望将对象的构造与使用分离开时。 ### 示例代码(Java实现): ```java // 产品角色 public class Computer { private String cpu; private ...

    C#视频-面向对象设计模式纵横谈(4):Builder 生成器模式(创建型模式)

    Builder模式是一种创建型设计模式,它提供了一种创建复杂对象的灵活方式,将对象的创建过程逐步分解,使得创建过程可以独立于使用过程。在C#编程中,Builder模式经常被用于构造对象,特别是当对象的构建过程复杂,...

    生成器模式builder

    Builder模式属于创建型设计模式,它的核心思想是将对象的创建过程与对象本身分离,使得同样的构建过程可以创建不同的表示。 在Java或其他面向对象语言中,生成器模式通常包括四个主要角色:产品(Product)、建造者...

    软件体系结构Builder模式浅谈

    工厂模式关注的是创建对象,而Builder模式关注的是如何一步一步地构造一个复杂的对象。 在实际编程中,Builder模式可以通过以下步骤实现: 1. 定义产品类,包含所有可能的组成部分。 2. 创建抽象Builder接口,定义...

Global site tag (gtag.js) - Google Analytics