【问题标题】:Builder pattern for methods with exception handling具有异常处理的方法的构建器模式
【发布时间】:2017-07-19 11:21:19
【问题描述】:

我有几个看起来像这样的方法:

public void do(A a, B b);

public void do(A A, C c);

public void do(D d, A a);

public void do(D d, E e, X x, F f, Optional<A> a);

等等,大约有几十种方法基本相同,但参数不同。

现在我考虑使用构建器模式,让我可以使用如下功能:

withA(a).withB(b).withX(x).do();

但是,问题在于几十种方法中的一种会引发异常。如果我使用构建器模式,那么do() 将不得不抛出此异常,因此所有客户端都必须处理它。在我看来,这听起来是个问题。

我的问题:

  • 这是个问题吗?
  • 如果是,如何避免?

【问题讨论】:

  • 为什么会抛出这个异常?是验证吗?您可以提取该验证a,并且只需要传递有效的参数...
  • 当 do 中的计算结果与预期不符时,我抛出异常。
  • 这意味着您在 setter 中执行业务逻辑。这违反了单一职责模式
  • This question 相关/有帮助。
  • @TimothyTruckle 是的,但现在无法改变。

标签: java oop exception-handling


【解决方案1】:

是的。这是一个问题。

你可以:

  1. 如果您知道如何处理异常并且要设置的字段是可选的,则捕获异常。

  2. 但是,如果在您尝试设置必填字段时抛出异常,则意味着出现问题,整个操作应该会失败。

【讨论】:

    【解决方案2】:

    总是有简单的“把它变成一个 RuntimeException”的解决方案。

    只需尝试/捕获即可;在 catch 中,创建一个新的 RuntimeException 来包裹检查的异常 - 并重新抛出它。以及 javadoc 中的文档。

    【讨论】:

      【解决方案3】:

      当您使用恰好导致异常的类型作为参数时,您可以更改上下文。

      请注意,这不是最聪明的想法,可能不应该被鼓励。

      示例构建器:

      class ParamA{}    
      class ParamB{}
      
      class Builder {
      
          // ... More Stuff ...
      
          public Builder with(ParamA p){
              // x happens here
              return this;
          }
      
          public BuilderB with(ParamB p){
              // y happens here
              return new BuilderB(this);
          }
      
          public void doWork(){
              System.out.println("I did my stuff");
          }
      }
      
      
      class BuilderB{
          private BuilderB(){}
      
          public BuilderB(Builder b) {
              //Initialize with stuff from b
          }
      
          public BuilderB with(ParamB p){
              // y happens here
              return this;
          }
          public BuilderB with(ParamA p){
              // x happens here
              return this;
          }
      
          public void doStuff() throws Exception{
              throw new Exception("poof");
          }
      }
      

      用法:

      void example() {
      
          ParamA a = new ParamA();
          ParamB b = new ParamB();
      
          // doWork in builder doesn't throw, we're good
          new Builder().with(a).with(a).doWork();
      
          try {
              // stuff in BuilderB trhows, surround w/ try catch
              c.new Builder().with(a).with(b).doStuff();
          } catch (Exception ex) {
              System.out.println("Exception goes " + ex.getMessage());
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多