Java 抽象层级Step Builder模式实现带互斥属性规则的流式构造方案问询
可行实现方案
核心思路是通过接口拆分步骤边界,用工厂逻辑解耦上层通用入口与下层具体Builder实现,完全满足你提出的两项要求。
核心实现逻辑
- 步骤接口隔离:将每个阶段允许调用的方法拆分到独立的接口中,每个接口仅暴露当前阶段可操作的方法,从编译层面杜绝跨阶段调用的可能。
- 通用属性下沉传递:基础步骤统一收集所有通用属性,进入特殊规则配置阶段时,将已收集的通用属性一次性传入具体特殊Builder,特殊Builder仅实现特殊属性配置接口,完全不暴露基础属性修改入口。
- 统一入口封装:所有调用从通用Builder入口发起,用户完全不需要感知底层具体Builder的实现细节。
代码实现示例
1. 定义步骤接口
// 第一步:仅允许设置基础属性1 public interface BaseStep1 { BaseStep2 withBaseProperty1(String property1); } // 第二步:仅允许设置互斥的基础属性2或3,选其中一个后进入特殊规则选择阶段 public interface BaseStep2 { SpecialRuleEntry withBaseProperty2(String property2); SpecialRuleEntry withBaseProperty3(String property3); } // 基础步骤完成入口,仅暴露各规则类型的接入方法,不暴露任何基础属性修改入口 public interface SpecialRuleEntry { SpecialRuleStep forSpecialRule(); // 新增其他规则类型时仅需在此加对应入口方法即可 // AnotherRuleStep forAnotherRule(); } // 具体特殊规则的配置接口,仅暴露特殊属性的设置方法 public interface SpecialRuleStep { SpecialRuleStep withSpecial1(String special1); SpecialRuleStep withSpecial2(String special2); Rule build(); }
2. 实现通用入口Builder
public class GeneralBuilder implements BaseStep1, BaseStep2, SpecialRuleEntry { // 存储所有通用基础属性 private String property1; private String property2; private String property3; // 对外统一入口 public static BaseStep1 builder() { return new GeneralBuilder(); } @Override public BaseStep2 withBaseProperty1(String property1) { this.property1 = property1; return this; } @Override public SpecialRuleEntry withBaseProperty2(String property2) { this.property2 = property2; return this; } @Override public SpecialRuleEntry withBaseProperty3(String property3) { this.property3 = property3; return this; } @Override public SpecialRuleStep forSpecialRule() { // 将已收集的通用属性传入具体特殊Builder,上层完全不感知实现细节 return new SpecialRuleBuilder(property1, property2, property3); } }
3. 实现具体特殊规则Builder
class SpecialRuleBuilder implements SpecialRuleStep { // 通用属性用final修饰,构造后不允许修改 private final String property1; private final String property2; private final String property3; private String special1; private String special2; // 仅通过构造方法接收通用属性,不对外暴露任何基础属性修改方法 public SpecialRuleBuilder(String property1, String property2, String property3) { this.property1 = property1; this.property2 = property2; this.property3 = property3; } @Override public SpecialRuleStep withSpecial1(String special1) { this.special1 = special1; return this; } @Override public SpecialRuleStep withSpecial2(String special2) { this.special2 = special2; return this; } @Override public Rule build() { // 自定义构造逻辑 return new SpecialRule(property1, property2, property3, special1, special2); } }
最终调用效果
完全符合你期望的流式调用体验,编译期强制约束步骤顺序:
Rule result = GeneralBuilder.builder() .withBaseProperty1("asdas") // 第一步仅能调用该方法 .withBaseProperty2("asd") // 第二步选择属性2后,属性3的方法自动隐藏 .forSpecialRule() // 选择规则类型后进入特殊属性配置阶段 .withSpecial1("asd") // 仅能看到特殊属性配置方法,完全无基础属性修改入口 .withSpecial2("xxx") .build();
扩展优化方案
如果需要进一步降低新增规则的改造成本,可以用规则类型枚举+工厂模式替换SpecialRuleEntry中的硬编码方法,实现新增规则无需修改上层接口:
- 定义
RuleType枚举,枚举值对应所有规则类型 - 工厂类维护
RuleType与对应特殊Builder构造器的映射关系 - SpecialRuleEntry提供
SpecialRuleStep forRuleType(RuleType type)方法,内部通过工厂获取对应Builder实例
内容的提问来源于stack exchange,提问作者HectorLector
相关产品推荐
相关产品推荐

