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/
相关推荐
7. **建造者模式**(BuilderPattern):将复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。它能确保构建过程的正确性和灵活性。 8. **桥接模式**(BridgePattern):将抽象部分与实现部分...
本资源“DesignPattern::pencil:设计模式_java实现以及详解”提供了一套详细的学习材料,帮助开发者理解和应用设计模式。 该资源的作者是“养码青年-Style”,他通过这个项目记录了自己的设计模式学习过程。鼓励...
4. 建造者模式(Builder Pattern): 建造者模式将复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。在C#中,建造者模式常用于创建复杂的对象,比如GUI组件或数据库记录,通过分离构造过程和表示...
"Design*Pattern*Framework*4.5" 可能指的是一个基于 .NET Framework 4.5 的设计模式实现或教程集合。 设计模式是经验丰富的软件开发者的智慧结晶,它们被分为三类:创建型、结构型和行为型。创建型模式涉及对象的...
"DesignPattern:C#设计模式示例"这个资源很可能是包含多个C#实现的设计模式示例代码库。 设计模式通常分为三类:创建型、结构型和行为型。每种模式都解决了特定场景下的问题,并提供了良好的代码组织和扩展性。 ...
designpattern design pattern for java 描述: pattern.p001.factory :工厂模式。 pattern.p002.abstractfactory : 抽象工厂模式。 pattern.p003.singletonEH : 单例模式(饿汉式)。 pattern.p003.singletonLH : ...
建造者模式(builderPattern) 原型模式(prototypePattern) 适配器模式(adapterPattern) 桥接模式(bridgePattern) 过滤器模式(filterPattern) 组合模式(compositePattern) 装饰器模式(decoratorPattern) 外观模式...
设计模式是软件工程中的一种最佳实践,用于解决在软件设计中常见的...以上就是这个DesignPattern小Demo中可能会涵盖的设计模式,通过这些模式的实例,你可以更好地理解和应用它们到实际项目中,提升你的Java编程能力。
这个名为"DesignPattern:这是针对不同设计人员的测试项目"的压缩包,显然是一个与设计模式相关的学习或测试资源,特别关注的是Java语言的应用。Scott可能是该项目的创建者或者主要贡献者,而“调整”可能指的是对...
4. 建造者模式(Builder Pattern):将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。建造者模式特别适用于创建的对象复杂,但需要被分解成多个步骤来创建。 5. 原型模式(Prototype ...
设计模式是软件工程中的一种最佳实践,它是在特定...在"designPattern"项目中,你将有机会亲手实践这些设计模式,理解它们的用途、结构和行为,这将有助于提升你的编程技能和设计能力,更好地应对复杂的软件开发挑战。
在这个"DesignPattern-master"的项目中,可能包含了以上提到的各种设计模式的实现示例,每个模式可能有一个或多个Java类来演示。通过阅读和分析这些示例,开发者可以更好地理解设计模式的工作原理,并能在实际项目中...
DesignPattern-master这个压缩包可能包含了一个关于设计模式的项目或者教程资源。 设计模式分为三类:创建型模式(Creational Patterns)、结构型模式(Structural Patterns)和行为型模式(Behavioral Patterns)...
在"DesignPattern-master"这个压缩包中,你可能找到的文件结构和内容包括: 1. **单例模式(Singleton)**:确保一个类只有一个实例,并提供一个全局访问点。在.NET中,通常使用静态属性或双重检查锁定来实现。 2....
最后,还有建造者模式(Builder)用于分步骤构建复杂对象,隔离对象的构造过程,使得构造过程和表示分离。 以上只是部分设计模式的简介,Head First 设计模式书中详细讲解了23种经典设计模式,每种模式都有实际的...
设计模式(Design Pattern)是软件工程中的一种经验总结,它是在特定上下文中为解决常见问题而提出的一套可复用的解决方案。设计模式并不直接实现为代码,而是提供了一种在面向对象设计中如何处理常见问题的指南。...
在"designPattern-master"这个项目中,你可以期待找到以上所有或部分设计模式的Java代码实现,这将是一个宝贵的资源,可以帮助你深入理解和掌握这些模式的实际运用,提升你的编程技能。通过阅读和实践这些代码,你...
这个名为"DesignPattern"的压缩包文件很可能包含了一个Java实现的各种设计模式的示例程序。 在这个"DesignPattern-master"目录中,我们可以期待找到一系列与设计模式相关的Java源代码文件(.java),每个文件或...
"designPattern-main"可能包含了关于这些设计模式的详细解释、示例代码以及可能的改进和修正。通过学习这个压缩包中的资料,开发者不仅可以深入理解各种设计模式,还能了解到"정정전"对这些模式的独特见解和实践经验...
在Java中,Builder模式常用于创建复杂的对象结构。 5. **原型模式**:用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象。Java中可以利用`java.lang.Cloneable`接口实现。 6. **适配器模式**:将一...