2013-04-25 76 views
1

一种方法返回一些结果,使得一些“尝试”来构建它。成功的第一次尝试应该返回。如果没有他们的成功异常应抛出:错误/异常累积设计模式

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()方法,考虑到可扩展性和可维护性?

回答

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对象,以便不同的命令可以采用不同类型的东西(放在上下文中)。