现在的位置: 首页 > 综合 > 正文

Effective Java Item2:当构造方法的参数(尤其是可选参数)比较多时使用Builder模式

2013年09月12日 ⁄ 综合 ⁄ 共 4526字 ⁄ 字号 评论关闭

 Item2 Consider using a Builder when faced with many constructor parameters

当构造方法(静态工厂方法)包含多个参数时,考虑使用Builder

当一个类的构造方法包含多个参数时,其中只有固定的几个参数是必须的,而其他的参数都是可选的,此时使用构造方法或者静态工厂方法都很不方便。

一般来说,有以下几种方式来对应这种情况:

1. 采用telescoping constructor模式。即提供一个只有必要参数的构造器,第二个构造器有一个可选参数,第三个有两个可选参数,依此类推,最后一个构造器包含所有可选参数。这种模式的缺点在于为客户端(使用API的地方) 编程带来了麻烦,一旦参数顺序错误,将会导致难以发现的错误,另外这样的代码的可读性也非常低。

2. 使用JavaBeans模式。即通过无参构造方法构造实例,然后使用setter方法进行属性的设置。这种方式不会有1中所说的缺点。但是JavaBeans模式有其自身的缺点:由于实例的完整构造过程是通过多次调用完成的,所以就存在实例不一致性(线程并发的情况)的问题。同时,JavaBeans模式阻止了类称为常量类,这就要求客户端进行并发的控制。

[Immutable Class]

The term immutable is used to mean that once an object is created, its content cannot be changed.
"String" class is a best example of an immutable class.
To create a object which is immutable u need to make sure that the following conditions are met.
a) The Class should be final.
b) The Properties of the class should be private and should not have any setter methods.
The above mentioned are bare minimum conditions that needs to be satisfied to make the object immutable.

 

3. 使用Builder模式。Builder Pattern综合了telescoping pattern的安全性和JavaBeans。客户端通过使用必须的参数来构造或者使用静态方法来获取Builder类的实例。然后客户端调用Builder实例的每个类似于setter的方法来设置Builder实例的属性。最后,调用Builder类的build方法来获取一个不变的实例。Builder类是目标类的inner static类。

类实例如下:

Telescoping Constructor Pattern

package com.googlecode.javatips4u.effectivejava.builder;

 

public class TelescopingConstructorPattern {

              public static class Dog {

                            private String name;

                            private int weight;

                            private int height;

                            private int age;

                            private int type;

                            private int price;

 

                            public Dog(String name) {

                                          this.name = name;

                            }

 

                            public Dog(String name, int weight) {

                                          super();

                                          this.name = name;

                                          this.weight = weight;

                            }

 

                            public Dog(String name, int weight, int height) {

                                          super();

                                          this.name = name;

                                          this.weight = weight;

                                          this.height = height;

                            }

 

                            public Dog(String name, int weight, int height, int age) {

                                          super();

                                          this.name = name;

                                          this.weight = weight;

                                          this.height = height;

                                          this.age = age;

                            }

 

                            public Dog(String name, int weight, int height, int age, int type) {

                                          super();

                                          this.name = name;

                                          this.weight = weight;

                                          this.height = height;

                                          this.age = age;

                                          this.type = type;

                            }

 

                            public Dog(String name, int weight, int height, int age, int type,

                                                        int price) {

                                          super();

                                          this.name = name;

                                          this.weight = weight;

                                          this.height = height;

                                          this.age = age;

                                          this.type = type;

                                          this.price = price;

                            }

 

                            public String getName() {

                                          return name;

                            }

 

                            public int getWeight() {

                                          return weight;

                            }

 

                            public int getHeight() {

                                          return height;

                            }

 

                            public int getAge() {

                                          return age;

                            }

 

                            public int getType() {

                                          return type;

                            }

 

                            public int getPrice() {

                                          return price;

                            }

              }

 

              public static void main(String[] args) {

                            Dog houseDog = new Dog("bruce",

                                                        15,//weight 15kg

抱歉!评论已关闭.