遇到多个构造器参数时要考虑用构建器Bulider

静态工厂和构造器有个共同的局限性:他们都不能很好的扩展大量的可选参数,
比如包装食品营养成分标签,含量,卡路里,等等,有可能会超过20个可选域,对于这样的类,应该用那种构造器或静态方法来写呢,

构造器:
程序员一般习惯采用重载构造器来实现,第一个构造器,提供一个必要参数,第二个构造器提供,一个必要参数,一个可选参数,依次类推.

public NutritionFacts(int servingSize){}
public NutritionFacts(int servingSize,int calories){}
public NutritionFacts(int servingSize,int calories,int fat){}

缺点
构造器调用通常需要许多本不想设置参数,但是不得不为他们传递值.随着参数数目的增加,就很快失去了控制

javabean模式:
这种模式下调用一个午餐构造器来创建对象,然后调用setter方法来设置每个必要的参数,以及每个可选参数.

public class NutritionFacts{
private int servingSize=-1;
private int servings=-1;
private int calories=0;
...getter setter省略
}

优点:弥补了重叠构造器模式的不足,创建实例很容易,代码易读性强

NutritionFacts cocaCola=new NutritionFacts();
cocaCola.setServingSize(22);
cocaCola.setServings(22);
...

缺点:
其构造过程中被分到几个调用中,在构造过程中JavaBean可能处于不一致的状态,这种失败与包含错误代码,类无法仅仅通过检验构造器参数的有效性来保证一致性,试图使用不一致状态的对象,将会导致失败,这种失败与包含错误的代码大相径庭,因此它调试起来非常困难,另一点不足,JavaBean阻止了把类做成不可变类的可能,这就需要额外的努力来确保他的线程安全.

构建器模式:

public class NutritionFacts {

    private final int servingSize;
    private final int servings;
    private final int calories;
    private final int fat;
    private final int sodium;
    private final int carbohydrate;

    public static class Bulider{
        private  int servingSize;
        private  int servings;
        private  int calories=0;
        private  int fat=0;
        private  int sodium=0;
        private  int carbohydrate=0;

        public Bulider( int servingSize,int servings) {
            this.servings=servings;
            this.servingSize=servingSize;
        }
        public Bulider calories( int var) {
            this.calories=var;
            return this;
        }
        public Bulider fat( int var) {
            this.fat=var;
            return this;
        }
        public Bulider sodium( int var) {
            this.sodium=var;
            return this;
        }
        public Bulider carbohydrate( int var) {
            this.carbohydrate=var;
            return this;
        }

        public NutritionFacts bulid() {
            return new NutritionFacts(this);
        }
    }
    private NutritionFacts(Bulider bulider) {
        servings=bulider.servings;
        servingSize=bulider.servingSize;
        calories=bulider.calories;
        fat=bulider.calories;
        sodium=bulider.sodium;
        carbohydrate=bulider.carbohydrate;
    }


}
//客户端测试
@Test
public void codeTest() {
    NutritionFacts nutritionFacts=new NutritionFacts.Bulider(240, 8).
    calories(100).sodium(33).carbohydrate(22).bulid();
}

优势:
bulider可以有多个可变参数,构造器就像方法一样,只能有一可变参数,因为builder利用单独的方法来设置每个参数,想要多少个就key有多少个, 该模式十分灵活,可以利用单个bulider对象,参数可以在创建对象时调整,也可以根据不同对象改变,buliderkey自动填充某些域,例如每次创建对象时自动增加序列号
不足:
为了创建对象,必须先创建它的构建器,虽然创建构建器的开销在实践中可能不那么明显,但是在某些注重性能的情况下,可能就成问题,Bulider模式比重叠构造器模式更加冗长因此只有很多参数的时候才使用.

猜你喜欢

转载自blog.csdn.net/gameloftnet/article/details/78057102