第2条:遇到多个构造器参数时要考虑用构建器

重叠构造器模式可行,但是当有许多参数的时候,客户端代码会难以编写,并且仍然较难以阅读。--他的前提是,有很多种不同的构造器情况,也就是很多构造器参数不同,或者说(很多参数可选,因为很多参数有默认值)。
错误示例:
  1. // Telescoping constructor pattern - does not scale well! - Pages 11-12
  2. publicclassNutritionFacts {
  3. privatefinalintservingSize;// (mL)required
  4. privatefinalintservings;// (per container) required
  5. privatefinalintcalories;// optional
  6. privatefinalintfat;// (g) optional
  7. privatefinalintsodium;// (mg)optional
  8. privatefinalintcarbohydrate;// (g) optional
  9. publicNutritionFacts(intservingSize,intservings) {
  10. this(servingSize, servings,0);
  11. }
  12. publicNutritionFacts(intservingSize,intservings,
  13. intcalories) {
  14. this(servingSize, servings, calories,0);
  15. }
  16. publicNutritionFacts(intservingSize,intservings,
  17. intcalories,intfat) {
  18. this(servingSize, servings, calories, fat,0);
  19. }
  20. publicNutritionFacts(intservingSize,intservings,
  21. intcalories,intfat,intsodium) {
  22. this(servingSize, servings, calories, fat, sodium,0);
  23. }
  24. publicNutritionFacts(intservingSize,intservings,
  25. intcalories,intfat,intsodium,intcarbohydrate) {
  26. this.servingSize= servingSize;
  27. this.servings = servings;
  28. this.calories = calories;
  29. this.fat= fat;
  30. this.sodium = sodium;
  31. this.carbohydrate = carbohydrate;
  32. }
  33. publicstaticvoidmain(String[] args) {
  34. NutritionFacts cocaCola =
  35. newNutritionFacts(240,8,100,0,35,27);
  36. }
  37. }

替代方法:使用JavaBeans模式
  1. // JavaBeans Pattern - allows inconsistency, mandates mutability - Pages 12-13
  2. publicclassNutritionFacts {
  3. // Parameters initialized to default values (if any)
  4. privateintservingSize= -1;// Required; no default value
  5. privateintservings = -1;// " " ""
  6. privateintcalories =0;
  7. privateintfat=0;
  8. privateintsodium =0;
  9. privateintcarbohydrate =0;
  10. publicNutritionFacts() { }
  11. // Setters
  12. publicvoidsetServingSize(intval){ servingSize = val; }
  13. publicvoidsetServings(intval) { servings = val; }
  14. publicvoidsetCalories(intval) { calories = val; }
  15. publicvoidsetFat(intval){ fat = val; }
  16. publicvoidsetSodium(intval) { sodium = val; }
  17. publicvoidsetCarbohydrate(intval) { carbohydrate = val; }
  18. publicstaticvoidmain(String[] args) {
  19. NutritionFacts cocaCola =newNutritionFacts();
  20. cocaCola.setServingSize(240);
  21. cocaCola.setServings(8);
  22. cocaCola.setCalories(100);
  23. cocaCola.setSodium(35);
  24. cocaCola.setCarbohydrate(27);
  25. }
  26. }

本节建议使用的是Builder模式:
  1. // Builder Pattern - Pages 14-15
  2. publicclassNutritionFacts {
  3. privatefinalintservingSize;
  4. privatefinalintservings;
  5. privatefinalintcalories;
  6. privatefinalintfat;
  7. privatefinalintsodium;
  8. privatefinalintcarbohydrate;
  9. publicstaticclassBuilder {
  10. // Required parameters
  11. privatefinalintservingSize;
  12. privatefinalintservings;
  13. // Optional parameters - initialized to default values
  14. privateintcalories=0;
  15. privateintfat =0;
  16. privateintcarbohydrate=0;
  17. privateintsodium=0;
  18. publicBuilder(intservingSize,intservings) {
  19. this.servingSize = servingSize;
  20. this.servings= servings;
  21. }
  22. publicBuilder calories(intval)
  23. { calories = val;returnthis; }
  24. publicBuilder fat(intval)
  25. { fat = val;returnthis; }
  26. publicBuilder carbohydrate(intval)
  27. { carbohydrate = val;returnthis; }
  28. publicBuilder sodium(intval)
  29. { sodium = val;returnthis; }
  30. publicNutritionFacts build() {
  31. returnnewNutritionFacts(this);
  32. }
  33. }
  34. privateNutritionFacts(Builder builder) {
  35. servingSize= builder.servingSize;
  36. servings = builder.servings;
  37. calories = builder.calories;
  38. fat= builder.fat;
  39. sodium = builder.sodium;
  40. carbohydrate = builder.carbohydrate;
  41. }
  42. publicstaticvoidmain(String[] args) {
  43. NutritionFacts cocaCola =newNutritionFacts.Builder(240,8).
  44. calories(100).sodium(35).carbohydrate(27).build();
  45. }
  46. }

Builder方式不足:为了创建对象,必须先创建它的构建器。会有所开销。而且代码冗长。

但是,当大多数参数都是可选的时候,Builder模式就是一个不错的选择。(比如好多框架就用的这种方式:类的构造器或者静态工厂中具有多个参数)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值