是否存在Pass/Fail设计模式?如何架构返回成败结果的操作类?
嘿,这个场景我熟!你现在要解决的就是操作结果二态返回的问题——要么成功带业务数据,要么失败带错误详情。下面给你几个实用的架构方案,按需选择:
方案1:用统一的Result类封装两种状态
这是最直接的方案,把成功/失败的信息都塞进一个统一的结果类里,用状态标记区分分支。
先定义封装类:
class Result { private final boolean isSuccess; private final Pass passData; private final Fail failData; // 私有构造,通过静态工厂方法创建实例,避免无效状态 private Result(boolean isSuccess, Pass passData, Fail failData) { this.isSuccess = isSuccess; this.passData = passData; this.failData = failData; } // 成功结果的工厂方法 public static Result success(Pass pass) { return new Result(true, pass, null); } // 失败结果的工厂方法 public static Result failure(Fail fail) { return new Result(false, null, fail); } // Getter方法,按需添加 public boolean isSuccess() { return isSuccess; } public Pass getPassData() { return passData; } public Fail getFailData() { return failData; } }
然后Operator类的方法就返回这个Result:
class Operator { public Result performBigOperation() { // 模拟业务逻辑判断 if (checkSuccessCondition()) { Pass pass = new Pass(); pass.someGoodStuff = 100; pass.someOtherGoodStuff = 99.9; return Result.success(pass); } else { Fail fail = new Fail(); fail.failureMsg = "参数校验不通过"; fail.howMuchOperationWasOffBy = 0.5f; return Result.failure(fail); } } private boolean checkSuccessCondition() { // 实际的成功判断逻辑 return Math.random() > 0.5; } }
优点:简单直观,调用方只需判断isSuccess()就能分支处理,不用处理复杂的类型转换;缺点:如果后续要扩展更多状态(比如「部分成功」),需要修改Result类,扩展性一般。
方案2:用接口+实现类的多态模式
如果需要更好的扩展性,比如以后可能新增「部分成功」这类状态,可以定义一个顶层接口,让Pass和Fail都实现它,利用多态返回不同结果。
先定义接口和实现类:
// 顶层结果接口,标记这是一个操作结果 interface OperationResult {} class Pass implements OperationResult { int someGoodStuff; double someOtherGoodStuff; } class Fail implements OperationResult { String failureMsg; float howMuchOperationWasOffBy; }
Operator类的方法返回OperationResult:
class Operator { public OperationResult performBigOperation() { if (checkSuccessCondition()) { Pass pass = new Pass(); // 赋值逻辑 return pass; } else { Fail fail = new Fail(); // 赋值逻辑 return fail; } } private boolean checkSuccessCondition() { return Math.random() > 0.5; } }
调用方可以用instanceof判断类型(Java 16+支持模式匹配,简化代码):
Operator operator = new Operator(); OperationResult result = operator.performBigOperation(); if (result instanceof Pass pass) { // 直接使用pass对象处理成功数据 System.out.println("成功:" + pass.someGoodStuff); } else if (result instanceof Fail fail) { // 直接使用fail对象处理失败信息 System.out.println("失败:" + fail.failureMsg); }
优点:扩展性极强,新增结果类型只需加一个实现类即可;缺点:调用方需要做类型判断,不过Java 16+的模式匹配已经大大简化了这个过程。
方案3:用Optional+自定义异常(适合失败为异常场景)
如果失败属于意外异常情况(不是业务逻辑中预期的正常分支),比如操作本应大概率成功,失败是因为系统错误、资源耗尽等,可以用Optional返回成功数据,失败时抛出携带Fail信息的自定义异常。
先定义自定义异常:
class OperationFailureException extends Exception { private final Fail failData; public OperationFailureException(Fail failData) { super(failData.failureMsg); this.failData = failData; } public Fail getFailData() { return failData; } }
Operator类的方法:
class Operator { public Optional<Pass> performBigOperation() throws OperationFailureException { if (checkSuccessCondition()) { Pass pass = new Pass(); // 赋值逻辑 return Optional.of(pass); } else { Fail fail = new Fail(); fail.failureMsg = "数据库连接超时"; fail.howMuchOperationWasOffBy = 0.8f; throw new OperationFailureException(fail); } } private boolean checkSuccessCondition() { return Math.random() > 0.5; } }
调用方通过try-catch处理:
Operator operator = new Operator(); try { Optional<Pass> maybePass = operator.performBigOperation(); maybePass.ifPresent(pass -> { // 处理成功数据 System.out.println("成功:" + pass.someGoodStuff); }); } catch (OperationFailureException e) { Fail fail = e.getFailData(); // 处理失败信息 System.out.println("失败原因:" + fail.failureMsg); }
优点:符合Java异常处理的语义,把异常情况和正常分支明确区分;缺点:不适合失败是业务预期分支的场景(比如用户输入错误导致的失败)。
最后给个选型建议:
- 场景简单、后续无扩展需求 → 选方案1;
- 需要扩展性、可能新增结果类型 → 选方案2;
- 失败属于意外异常情况 → 选方案3。
内容的提问来源于stack exchange,提问作者code11
相关产品推荐
相关产品推荐

