博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
builder模式的新学习
阅读量:5235 次
发布时间:2019-06-14

本文共 4115 字,大约阅读时间需要 13 分钟。

builder模式的新学习

静态工厂和构造器有个共同的局限性:他们不能很好的扩展到大量的可选参数。大多数产品在牧歌可选与中都会有非零的值

对于这种类,应该使用哪种构造器或者静态方法来进行编写?程序员一般习惯采用重叠构造器(telescoping constructor)模式。在这种模式下,你可以第一个只有必要参数的构造器,第二个构造器有一个可选参数,第三个有两个可选参数,以此类推,最后一个构造器包含所有的可选参数。

public class NutritionFacts {    private final int servingSize;  //required    private final int servings;     //required    private final int calories;     //optional    private final int fat;          //optional    private final int sodium;       //optional    private final int carbohydrate; //optional        public NutritionFacts(int servingSize,int servings){        this(servingSize,servings,0);    }    public NutritionFacts(int servingSize,int servings,int calories){        this(servingSize,servings,calories,0);    }    public NutritionFacts(int servingSize,int servings,int calories,int fat){        this(servingSize,servings,calories,fat,0);    }    public NutritionFacts(int servingSize,int servings,int calories,int fat,int sodium){        this(servingSize,servings,calories,fat,sodium,0);    }    public NutritionFacts(int servingSize,int servings,int calories,int fat,int sodium,int carbohydrate){        this.servingSize = servingSize;        this.servings = servings;        this.calories = calories;        this.fat = fat;        this.sodium = sodium;        this.carbohydrate = carbohydrate;    }}

当我们想要穿件实例的时候,就利用参数列表最短的构造器,但是该列表包含了要设置的所有参数:

NutritionFacts cocaCloa = new NutritionFacts(240,8,100,0,35,27);

这个构造器通常需要许多你本不想设置的参数,但是不能不为它传递值。在这个例子中,我们给fat传递了一个值为0。如果“仅仅”只有6个参数,看起来并不算太早,问题是随着参数数目的增加,它很快就会失去控制。

使用JavaBean模式,也能够代替这种问题。遗憾的是在一定的情况下,我们需要额外的努力来保证它的安全性。

幸运的是,还有新的替代方法,既能够保证向重叠构造器模式那样安全,也能够保证像JavaBean模式的那么好的可读性。这就是Builder模式的一种形式。不直接生成想要的对象。然后客户端利用所有必要的参数调用构造器(或者静态工厂),得到一个builder对象。然后客户端在builder对象上调用类似于setting的方法,来设置每个相关的可选参数。最后,客户端调用午餐的build方法来生成不可变的对象。这个builder是他构建的类的静态成员类。

//Builder Patternpublic class NutritionFacts{    private final int servingSize;  //required    private final int servings;     //required    private final int calories;     //optional    private final int fat;          //optional    private final int sodium;       //optional    private final int carbohydrate; //optional        public static class Builder{        private final int servingSize;  //required        private final int servings;     //required        private int calories;     //optional        private int fat;          //optional        private int sodium;       //optional        private int carbohydrate; //optional                public Builder(int servingSize,int servings){            this.servingSize = servingSize;            this.servings = servings;        }        public Builder calories(int val){            this.calories = val;            return this;        }        public Builder fat(int val){            this.fat = val;            return this;        }        public Builder sodium(int val){            this.sodium = val;            return this;        }        public Builder carbohydrate(int val){            this.carbohydrate = val;            return this;        }        public NutritionFacts build(){            return new NutritionFacts(this);        }    }    private NutritionFacts(Builder builder){        this.servingSize = builder.servingSize;        this.servings = builder.servings;        this.calories = builder.calories;        this.fat = builder.fat;        this.sodium = builder.sodium;        this.carbohydrate = builder.carbohydrate;    }}

注意NutrtionFacts是不可变的,所有的默认参数都是单独放在一个地方。builder的setter方法返回builder本身,以便可以把调用连接起来。

NutritionFacts nutritionFacts =     new NutritionFacts.Builder(240, 8)    .calories(100)    .sodium(35)    .carbohydrate(27)    .build();

这样的调用客户端代码很容易编写,更为重要的是易于阅读。

build方法可以检验这些约束条件。将参数从builder拷贝到对象中之后,并在对象域而不是builder域中对他们进行检验。如果违反了约束条件,build方法就应该抛出IllegalStateException。

Builder 模式自身的不足。为了创建对象,必须先创建它的构造器。虽然创建构造器的开销在实践中可能并不明显,但是在某些十分注重性能的情况下,可能就成问题了。

Builder 模式还比重叠构造器模式更加冗长,因此它只能在有很多参数的时候才使用。比如4个或者更多的参数。但是记住,将来你可能添加参数。如果一开始就是用构造器或者静态工厂,等类需要更多的参数时才添加构造器就会无法控制,那些过时的构造器或者静态工厂显得十分的不协调。因此,通常最好一开始就是用构造器。

简而言之,如果类的构造器或者静态工厂中具有多个参数,设计这种类的时,Builder模式就是种不错的选择,特别是当大多数的参数都是可选的时候。

转载于:https://www.cnblogs.com/mr-cc/p/5772980.html

你可能感兴趣的文章
layui父页面执行子页面方法
查看>>
如何破解域管理员密码
查看>>
Windows Server 2008 R2忘记管理员密码后的解决方法
查看>>
IE11兼容IE8的设置
查看>>
windows server 2008 R2 怎么集成USB3.0驱动
查看>>
Foxmail:导入联系人
查看>>
vue:axios二次封装,接口统一存放
查看>>
vue中router与route的区别
查看>>
js 时间对象方法
查看>>
网络请求返回HTTP状态码(404,400,500)
查看>>
Spring的JdbcTemplate、NamedParameterJdbcTemplate、SimpleJdbcTemplate
查看>>
Mac下使用crontab来实现定时任务
查看>>
303. Range Sum Query - Immutable
查看>>
图片加载失败显示默认图片占位符
查看>>
【★】浅谈计算机与随机数
查看>>
解决 sublime text3 运行python文件无法input的问题
查看>>
javascript面相对象编程,封装与继承
查看>>
Atlas命名空间Sys.Data下控件介绍——DataColumn,DataRow和DataTable
查看>>
Java中正则表达式的使用
查看>>
算法之搜索篇
查看>>