`
DavyJones2010
  • 浏览: 148596 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Design Pattern: Builder Pattern

阅读更多

Builder Pattern:

     The builder pattern is a design pattern that allows for the step-by-step creation of complex objects using the correct sequence of actions.

     The construction is controlled by a director object that only needs to know the type of object it is to create.

1. Motivation

    The more complex an application is, the complexity of classes and objects used increases.

    Complex objects are made of parts produced by other objects that need special care when being built.

    An application might need a mechanism for building complex objects that is independent from the ones that make up the object.

    The pattern allows a client object to construct a complex object by specifying only its type and content, being shielded from the details related to the object's representation.

    The way the construction process can be used to create different representations.

    The logic of this process is isolated from the actual steps used in creating the complex object,

    so the process can be used again to create a different object from the same set of simple objects as the first one.

 

2. Intent

    1> Defines an instance for creating an object but letting subclasses decide which class to instantiate.

    2> Refers to the newly created object through a common interface.

 

3. Example

    1> Simple Example

package edu.xmu.oop.builder;

public class Person {
    private final String lastName; // required
    private final String firstName; // required
    private final String middleName; // optional
    private final String salutation;// optional
    private final String suffix;// optional
    private final String streetAddress;// optional
    private final String city;// optional
    private final String state;// optional
    private final boolean isEmployed;// optional
    private final boolean isFemale;// required
    private final boolean isHomewOwner;// optional

    private Person(Builder personBuilder) {
	this.lastName = personBuilder.lastName;
	this.firstName = personBuilder.firstName;
	this.middleName = personBuilder.middleName;
	this.salutation = personBuilder.salutation;
	this.suffix = personBuilder.suffix;
	this.streetAddress = personBuilder.streetAddress;
	this.city = personBuilder.city;
	this.state = personBuilder.state;
	this.isEmployed = personBuilder.isEmployed;
	this.isFemale = personBuilder.isFemale;
	this.isHomewOwner = personBuilder.isHomewOwner;
    }

    public static class Builder {
	private final String lastName; // required
	private final String firstName; // required
	private String middleName = ""; // optional
	private String salutation = "";// optional
	private String suffix = "";// optional
	private String streetAddress = "";// optional
	private String city = "";// optional
	private String state = "";// optional
	private final boolean isFemale;// required
	private boolean isEmployed = false;// optional
	private boolean isHomewOwner = false;// optional

	public Builder(String lastName, String firstName, boolean isFemale) {
	    super();
	    this.lastName = lastName;
	    this.firstName = firstName;
	    this.isFemale = isFemale;
	}

	public Builder setMiddleName(String middleName) {
	    this.middleName = middleName;
	    return this;
	}

	public Builder setSalutation(String salutation) {
	    this.salutation = salutation;
	    return this;
	}

	public Builder setSuffix(String suffix) {
	    this.suffix = suffix;
	    return this;
	}

	public Builder setStreetAddress(String streetAddress) {
	    this.streetAddress = streetAddress;
	    return this;
	}

	public Builder setCity(String city) {
	    this.city = city;
	    return this;
	}

	public Builder setState(String state) {
	    this.state = state;
	    return this;
	}

	public Builder setEmployed(boolean isEmployed) {
	    this.isEmployed = isEmployed;
	    return this;
	}

	public Builder setHomewOwner(boolean isHomewOwner) {
	    this.isHomewOwner = isHomewOwner;
	    return this;
	}

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

    @Override
    public String toString() {
	return "Person [lastName=" + lastName + ", firstName=" + firstName
		+ ", middleName=" + middleName + ", salutation=" + salutation
		+ ", suffix=" + suffix + ", streetAddress=" + streetAddress
		+ ", city=" + city + ", state=" + state + ", isEmployed="
		+ isEmployed + ", isFemale=" + isFemale + ", isHomewOwner="
		+ isHomewOwner + "]";
    }

}
package edu.xmu.oop.builder;

import org.apache.log4j.Logger;
import org.junit.Test;

public class PersonTest {
    private static final Logger logger = Logger.getLogger(PersonTest.class);

    @Test
    public void buildTest() {
	Person p = new Person.Builder("Yang", "Kunlun", false)
		.setCity("Shanghai").setEmployed(true)
		.setStreetAddress("Chenhui RD").build();
	logger.info(p);
    }
}

    Attention:
        1> Person.Build has to be public static for outter class to have access to this Builder class

        2> Person.Build has to have the same attributes as Person have and have to unfinalize the optional attributes.

        3> Person's constructor has to be private in that outter class cannot construct Person directly.

    2> Guava Example

package edu.xmu.oop.builder;

public class ImmutableList<E> {
    private final transient Object[] array;

    private ImmutableList(Object[] array) {
	this.array = array;
    }

    public static <E> Builder<E> builder() {
	return new Builder<E>();
    }

    public static final class Builder<E> {
	static final int DEFAULT_INITIAL_CAPACITY = 4;

	Object[] contents;
	int size;

	public Builder() {
	    this(DEFAULT_INITIAL_CAPACITY);
	}

	Builder(int initialCapacity) {
	    this.contents = new Object[initialCapacity];
	    this.size = 0;
	}

	public Builder<E> add(E element) {
	    ensureCapacity(size + 1);
	    contents[size++] = element;
	    return this;
	}

	private void ensureCapacity(int minCapacity) {
	    // ...
	}

	@SuppressWarnings("unchecked")
	public ImmutableList<E> build() {
	    switch (size) {
	    case 0:
		return (ImmutableList<E>) new ImmutableList<Object>(
			new Object[0]); // return an empty list
	    default:
		if (size < contents.length) {
		    contents = arraysCopyOf(contents, size);
		}
		return new ImmutableList<E>(contents);
	    }
	}

	private Object[] arraysCopyOf(Object[] contents2, int size2) {
	    // ...
	    return new Object[0];
	}
    }

}
package edu.xmu.guava.collection;

import static org.junit.Assert.assertEquals;

import java.util.List;

import org.junit.Test;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;

public class ImmutableListTest {
    @Test
    public void immutableTest() {
	List<String> strList = ImmutableList.<String> builder().add("A")
		.add("B", "C").build();

	assertEquals(Lists.newArrayList("A", "B", "C"), strList);
    }
}

 

4. Conclusion

    1) Benefits and Advantages:

        1> The client code benefits greatly in terms of usability and readability.The parameters to the constructor are reduced and are provided in highly readable method calls.

        2> The ability to acquire an object in a single statement and state without the object in multiple states problem presented by using "set" methods.

             The Builder pattern is perfectly suited for an immutable class when that class features a large number of attributes

             and there is no need to pass in null for optional parameters to the constructor.

    2) Costs and Disadvantages:

        1> The number of lines of code of a given class must be essentially doubled for "set" method.

 

5. An interesting example to talk about:

    http://blog.frankel.ch/a-dive-into-the-builder-pattern#comment-7776

    Comments:

    1> If we need Builder Pattern, that usually means we are working with immutable classes(all properties are final).

    2> If we need mandatory fields, we should make that part of the Builder's constructor instead of using InvalidBuilder&ValidBuilder which would make code increasingly redundancy.

 

 

Reference Links:

1) http://www.oodesign.com/builder-pattern.html

2) http://www.javacodegeeks.com/2013/10/too-many-parameters-in-java-methods-part-3-builder-pattern.html

3) Effective Java 2nd Edition -Joshua Blosh

4) Guava Source Code -Kevin Bourrillion

5) http://www.ibm.com/developerworks/library/j-jtp02183/

 

分享到:
评论

相关推荐

    36种最新设计模式整理

    Design Pattern: Builder 模式 Design Pattern: Factory Method 模式 Design Pattern: Prototype 模式 Design Pattern: Singleton 模式 Design Pattern: Registry of Singleton 模式 Design Pattern: Default ...

    designpattern:java的设计模式

    designpattern design pattern for java 描述: pattern.p001.factory :工厂模式。 pattern.p002.abstractfactory : 抽象工厂模式。 pattern.p003.singletonEH : 单例模式(饿汉式)。 pattern.p003.singletonLH : ...

    java设计模式源码-DesignPattern:设计模式(Java实现源码)

    建造者模式(builderPattern) 原型模式(prototypePattern) 适配器模式(adapterPattern) 桥接模式(bridgePattern) 过滤器模式(filterPattern) 组合模式(compositePattern) 装饰器模式(decoratorPattern) 外观模式...

    C++设计模式(Design Pattern)范例源代码

    23种设计模式(Design Pattern)的C++实现范例,包括下面列出的各种模式,代码包含较详细注释。另外附上“设计模式迷你手册.chm”供参考。 注:项目在 VS2008 下使用。 创建型: 抽象工厂模式(Abstract Factory) 生成...

    单例模式源码java-DesignPattern:在个人自学阶段的23种设计模式代码的全部实现,全部使用Java编写,其中还包括各个设计模式在

    DesignPattern 在个人自学阶段的23种设计模式代码的全部实现,全部使用Java编写,其中还包括各个设计模式在源码中的使用,每种设计模式都举了一个简单的小例子来进行实现,并加以注释 包名解释 一、DesignPattern ...

    《Java Design Patterns》高清完整英文PDF版

    Learn how to implement design patterns in Java: each pattern in Java Design Patterns is a complete implementation and the output is generated using Eclipse, making the code accessible to all....

    Java.Design.Patterns.1537192353

    BUILDER PATTERN PROTOTYPE PATTERN ADAPTER PATTERN COMPOSITE PATTERN PROXY PATTERN FAÇADE PATTERN DECORATOR PATTERN FLYWEIGHT PATTERN TEMPLATE METHOD PATTERN MEDIATOR PATTERN CHAIN OF RESPONSIBILITY ....

    design-pattern-java.pdf

    对象的克隆——原型模式(四) 建造者模式-Builder Pattern 复杂对象的组装与创建——建造者模式(一) 复杂对象的组装与创建——建造者模式(二) 复杂对象的组装与创建——建造者模式(三) 七个结构型模式 七个...

    软件体系结构与设计模式课堂笔记.docx

    3.设计模式Design Pattern:创建型模式(厂模式Factory、抽象工厂模式Abstract Factory、单例模式Singleton、建造者模式Builder、原型模式Prototype和对象池模式Object Pool Pattern)、结构型模式(适配器模式、...

    Design.Patterns.Explained.Simply

    Builder Factory Method Object Pool Prototype Singleton Structural patterns Adapter Bridge Composite Decorator Facade Flyweight Private Class Data Proxy Behavioral patterns Chain of Responsibility ...

    uu-design-pattern:23种设计模式案例

    23种设计模式演示代码文件结构图gof23 |- creational(创建型模式) |- simplefactory 简单工厂模式案例 |- factorymethod 工厂方法模式案例 |- abstractfactory 抽象工厂模式案例 |- builder 建造者模式案例 |- ...

    design patterns elements of reusable object-oriented software

    ★附录A介绍了剩下的设计模式:Bridge(桥接)、Builder(生成器)、Chainof Responsibility(责任链)、Flyweight(蝇量)、Interpreter(解释器)、Mediator(中介者)、Memento(备忘录)、Prototype(原型)、...

    设计模式 design pattern

    3.2 Builder(生成器)—对象创建型 模式 63 3.3 Factory Method(工厂方法)— 对象创建型模式 70 3.4 Prototype(原型)—对象创建型 模式 87 3.5 Singleton(单件)—对象创建型 模式 84 3.6 创建型模式的讨论 89...

    Design Patterns Elements of Reusable Object-Oriented Software

    • What Is a Design Pattern? • Design Patterns in Smalltalk MVC • Describing Design Patterns • The Catalog of Design Patterns • Organizing the Catalog • How Design Patterns Solve Design ...

    DesignPattern.rar

    涵盖 Adapter Bridge Builder等13种设计模式的C++ 实现

    Java中的design-patterns::open_book:使用通俗易懂的案例,类图,以及配套学习笔记来详解Java的二十种设计模式!

    配套博客学习笔记: ://yubuntu0109.github.io/tags/design-and-pattern/ 参考书籍(推荐): 《Java设计模式 - 刘伟》 , 《图解设计模式 - [日]结城浩》 创建型模式 :check_mark:简单工厂模式( Simple Factor ...

    Apress.Pro.Design.Patterns.in.Swift

    The Builder Pattern Part 3 - The Structural Patterns Chapter 12. The Adapter Pattern Chapter 13. The Bridge Pattern Chapter 14. The Decorator Pattern Chapter 15. The Composite Pattern Chapter 16. ...

    design-pattern-test:设计模式学习

    design-pattern-test 设计模式学习练习 模式可以分为三大类:创建型模式(Creational Patterns)、结构型模式(Structural Patterns)、行为型模式(Behavioral Patterns) 序号 模式&描述 包括 1 创建型模式---...

    Design Pattern(GOF) CreatePattern Code

    描述设计模式中创建模型的代码,包括工厂模型,抽象工厂 原型 Builder,数据来源为设计模式一书

Global site tag (gtag.js) - Google Analytics