错误/异常累积设计模式

时间:2013-04-25 12:10:20

标签: java design-patterns exception-handling

一个方法返回一些结果,进行一些“尝试”来构建它。成功的第一次尝试应该返回。如果它们都没有成功,则应抛出异常:

class Calculator {
  public String calculate() throws Exception {
    // how do design it?
  }
  private String attempt1() throws Exception {
    // try to calculate and throw if fails
  }
  private String attempt2() throws Exception {
    // try to calculate and throw if fails
  }
  private String attempt3() throws Exception {
    // try to calculate and throw if fails
  }
}

重要的是要提到calculate抛出的异常应保留私有方法抛出的所有其他异常的堆栈跟踪。您如何建议设计calculate()方法,并考虑可扩展性和可维护性?

1 个答案:

答案 0 :(得分:2)

我会使用Composite和Command。

interface CalculateCommand {
     public void calculate(CalculateContext context);
}

现在为您想要的每次尝试创建一个实现。

接下来创建一个CompositeCommand - 这是一个大纲(你需要填写空白)

public class CompositeCalculateCommand implements CalculateCommand {

    CompositeCalculateCommand(List<CompositeCommand> commands) {
        this.commands = commands; // define this as a field
    }

    public void calculate(CommandContext context) {
         for (CalculateCommand command : commands) {
               try {
                   command.calculate(context);
               } catch(RuntimeException e) {
                   this.exceptions.add(e) // initialize a list to hold exceptions
               }
               if (context.hasResult) return; // break
         }
         // throw here. You didn't success since you never saw a success in your context.  You have a list of all exceptions.
    }

}

最后像

一样使用它
CalculateCommand allCommands = new CompositeCalculateCommand(someListOfCommands);
allCommands.calculate(someContextThatYouDefine);
// results now on context.

注意每个命令实现都是可测试的,因此这是非常易于维护的。如果需要添加计算,只需定义一种新类型CalculateCommand,这样就可以扩展。它也适用于依赖注入。注意我定义了一个CommandContext对象,因此不同的命令可以采用不同类型的东西(放在上下文中)。