Effective Java-2. 当构造方法参数过多时使用builder模式
背景
静态工厂和构造方法不能很好的拓展到很多可选参数的场景,因为参数过多的时候,调用其构造方法不太能知道每个位置参数的含义,容易出bug
那么为这个类编写什么样下的构造方法或静态工厂呢?
- 可伸缩构造方法模式
- 例子:
- 这个构造方法的调用需要许多你不想设置的参数,但是你不得不为它们传递一个值。 在这种情况下,我们为属性传递了 0 值。随着参数的增加容易失控
- 难以读懂
// Telescoping constructor pattern - does not scale well! class NutritionFacts { private final int servingSize; // (mL) required private final int servings; // (per container) required private final int calories; // (per serving) optional private final int fat; // (g/serving) optional private final int sodium; // (mg/serving) optional private final int carbohydrate; // (g/serving) 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; } }
- JavaBeans模式
- 使用无参构造方法创建对象,调用setter方法设置成员属性
- 构造对象过程被setter方法多次分割,可能处于不一致状态
- 排除了让类不可变的的可能性
// JavaBeans Pattern - allows inconsistency, mandates mutability public class NutritionFacts { // Parameters initialized to default values (if any) private int servingSize = -1; // Required; no default value private int servings = -1; // Required; no default value private int calories = 0; private int fat = 0; private int sodium = 0; private int carbohydrate = 0; public NutritionFacts() { } // Setters public void setServingSize(int val) { servingSize = val; } public void setServings(int val) { servings = val; } public void setCalories(int val) { calories = val; } public void setFat(int val) { fat = val; } public void setSodium(int val) { sodium = val; } public void setCarbohydrate(int val) { carbohydrate = val; } } // ==================调用形式=================== NutritionFacts cocaCola = new NutritionFacts(); cocaCola.setServingSize(240); cocaCola.setServings(8); cocaCola.setCalories(100); cocaCola.setSodium(35); cocaCola.setCarbohydrate(27);
Builder模式
- 可以生成流畅的API,易于阅读
- builder 可以有多个可变参数,因为每个参数都是在它自己的方法中指定的,可以将传递给多个调用的参数聚合到单个属性中
- 单个 builder 可以重复使用来构建多个对象,builder 的参数可以在构建方法的调用之间
进行调整,以改变创建的对象,可以在创建时自动添加一些属性(例如递增的序列号)
具体用法参考建造者模式!!!
缺点:
- 为了创建对象,必须创建一个Builder对象,可能会影响性能
- builder模式比神所构造方法模式冗长,因此builder模式适用有足够的参数(或者未来可能有)
本文来自博客园,作者:WYia,转载请注明原文链接:https://www.cnblogs.com/wyia/p/16978667.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!