重叠构造器模式可行,但是当有许多参数的时候,客户端代码会难以编写,并且仍然较难以阅读。--他的前提是,有很多种不同的构造器情况,也就是很多构造器参数不同,或者说(很多参数可选,因为很多参数有默认值)。
错误示例:
替代方法:使用JavaBeans模式
本节建议使用的是Builder模式:
Builder方式不足:为了创建对象,必须先创建它的构建器。会有所开销。而且代码冗长。
但是,当大多数参数都是可选的时候,Builder模式就是一个不错的选择。(比如好多框架就用的这种方式:类的构造器或者静态工厂中具有多个参数)
错误示例:
- // Telescoping constructor pattern - does not scale well! - Pages 11-12
- publicclassNutritionFacts {
- privatefinalintservingSize;// (mL)required
- privatefinalintservings;// (per container) required
- privatefinalintcalories;// optional
- privatefinalintfat;// (g) optional
- privatefinalintsodium;// (mg)optional
- privatefinalintcarbohydrate;// (g) optional
- publicNutritionFacts(intservingSize,intservings) {
- this(servingSize, servings,0);
- }
- publicNutritionFacts(intservingSize,intservings,
- intcalories) {
- this(servingSize, servings, calories,0);
- }
- publicNutritionFacts(intservingSize,intservings,
- intcalories,intfat) {
- this(servingSize, servings, calories, fat,0);
- }
- publicNutritionFacts(intservingSize,intservings,
- intcalories,intfat,intsodium) {
- this(servingSize, servings, calories, fat, sodium,0);
- }
- publicNutritionFacts(intservingSize,intservings,
- intcalories,intfat,intsodium,intcarbohydrate) {
- this.servingSize= servingSize;
- this.servings = servings;
- this.calories = calories;
- this.fat= fat;
- this.sodium = sodium;
- this.carbohydrate = carbohydrate;
- }
- publicstaticvoidmain(String[] args) {
- NutritionFacts cocaCola =
- newNutritionFacts(240,8,100,0,35,27);
- }
- }
替代方法:使用JavaBeans模式
- // JavaBeans Pattern - allows inconsistency, mandates mutability - Pages 12-13
- publicclassNutritionFacts {
- // Parameters initialized to default values (if any)
- privateintservingSize= -1;// Required; no default value
- privateintservings = -1;// " " ""
- privateintcalories =0;
- privateintfat=0;
- privateintsodium =0;
- privateintcarbohydrate =0;
- publicNutritionFacts() { }
- // Setters
- publicvoidsetServingSize(intval){ servingSize = val; }
- publicvoidsetServings(intval) { servings = val; }
- publicvoidsetCalories(intval) { calories = val; }
- publicvoidsetFat(intval){ fat = val; }
- publicvoidsetSodium(intval) { sodium = val; }
- publicvoidsetCarbohydrate(intval) { carbohydrate = val; }
- publicstaticvoidmain(String[] args) {
- NutritionFacts cocaCola =newNutritionFacts();
- cocaCola.setServingSize(240);
- cocaCola.setServings(8);
- cocaCola.setCalories(100);
- cocaCola.setSodium(35);
- cocaCola.setCarbohydrate(27);
- }
- }
本节建议使用的是Builder模式:
- // Builder Pattern - Pages 14-15
- publicclassNutritionFacts {
- privatefinalintservingSize;
- privatefinalintservings;
- privatefinalintcalories;
- privatefinalintfat;
- privatefinalintsodium;
- privatefinalintcarbohydrate;
- publicstaticclassBuilder {
- // Required parameters
- privatefinalintservingSize;
- privatefinalintservings;
- // Optional parameters - initialized to default values
- privateintcalories=0;
- privateintfat =0;
- privateintcarbohydrate=0;
- privateintsodium=0;
- publicBuilder(intservingSize,intservings) {
- this.servingSize = servingSize;
- this.servings= servings;
- }
- publicBuilder calories(intval)
- { calories = val;returnthis; }
- publicBuilder fat(intval)
- { fat = val;returnthis; }
- publicBuilder carbohydrate(intval)
- { carbohydrate = val;returnthis; }
- publicBuilder sodium(intval)
- { sodium = val;returnthis; }
- publicNutritionFacts build() {
- returnnewNutritionFacts(this);
- }
- }
- privateNutritionFacts(Builder builder) {
- servingSize= builder.servingSize;
- servings = builder.servings;
- calories = builder.calories;
- fat= builder.fat;
- sodium = builder.sodium;
- carbohydrate = builder.carbohydrate;
- }
- publicstaticvoidmain(String[] args) {
- NutritionFacts cocaCola =newNutritionFacts.Builder(240,8).
- calories(100).sodium(35).carbohydrate(27).build();
- }
- }
Builder方式不足:为了创建对象,必须先创建它的构建器。会有所开销。而且代码冗长。
但是,当大多数参数都是可选的时候,Builder模式就是一个不错的选择。(比如好多框架就用的这种方式:类的构造器或者静态工厂中具有多个参数)