2013-11-01 46 views
0

我正在寻找一些程序设计指导。类libarary的异常处理设计

我有一个类库来处理数据库中的数据。我有一个winforms应用程序,它是用户输入和管理数据的表示层。假设用户输入一些数据并尝试保存。从Winforms应用程序我做这样的事情:

MyTool theTool = new MyTool(); 
MyTool.FirstName = this.Textbox1.Text; 
MyTool.LastName = this.Textbox2.Text; 
//etc... 
int result = MyTool.SaveData(); //result is the ID of the inserted record. 

MyTool是我的类库中的一种类型。在这种类型中,我会有:

public int SaveData() 
{ 
    if (IsReadyForInput()) 
    { 
    //..open a DB connection and save out the data 
    //..get the ID of the saved record 
    } 
    else 
    { 
     throw new ArgumentException("One or more arguments prevented saving the data"); 
    } 
    return theID 
} 

private bool IsReadyForInput() 
{ 
    if (this.FirstName.Length == 0) 
    { return false; } 
    if (this.LastName.Length == 0) 
    {return false;} 
    return true; 
} 

现在,我感兴趣的是如何处理异常的最佳设计。例如,上述方法根本不具体,所以用户不知道什么是错的。所以,我可以改写这个做这样的事情:

public void SaveData() 
{ 
    string errMess = IsReadyForInput(); 
    if (errMess.Length == 0) 
    { 
     //..open a DB connection and save out the data 
     //..get the ID of the saved record 
    } 
    else { 
     throw new ArgumentException(errMess); 
    } 
    return theID 
} 

private string IsReadyForInput() 
{ 
    if (this.FirstName.Length == 0) 
    { return "Specify a first name"; } 
    if (this.LastName.Length == 0) 
    {return "Specify a last name";} 
    return true; 
} 

然而,它只是似乎很优雅(或快速)方法不被比较字符串长度,找到错误消息。我曾试图写的东西,如:

public void SaveData() 
{ 
    ValidateInput(); 
    //..open a DB connection and save out the data 
    return theID 
} 

private void ValidateInput() 
{ 
    if (this.FirstName.Length == 0) 
    { throw new ArgumentException("Specify a first name"; } 
    if (this.LastName.Length == 0) 
    {throw new ArgumentException("Specify a first name"; } 
} 

的问题,这是异常实际上是由ValidateInput时抛出的前端调用“保存数据”,所以当异常到达顶部,对我来说,它会似乎不太清楚(尤其是如果在MyTool中有多种方法调用“ValidateInput()”)。

此外,我不确定在前端处理异常的最佳方法是因为如果引发错误,ID永远不会返回。

我想我只是寻找一些如何处理这种情况和一般验证/错误处理的指导。谢谢你的帮助。

回答

1

我想知道的第一件事情是你是否需要抛出异常都当普通的控制流可能就足够了:

if (IsReadyForInput()) 
{ 
    //..open a DB connection and save out the data 
    //..get the ID of the saved record 
} 
else 
{ 
    //..do whatever you need in case of invalid input 
} 

这个建议最明显的问题是,我们是在一个方法某处您的类库以及一些所需的效果(向用户显示警告等)发生在WinForms图层中。然而,这表明了一个更好的解决方案;即,做在的WinForms代码验证:

if (IsReadyForInput()) 
{ 
    int result = theTool.SaveData(); 
    //...and whatever else should happen. 
} 
else 
{ 
    //..do whatever you need in case of invalid input 
} 

上述方法更简单,让你的程序的部分较少地依赖于对方(如MyTool并不需要关心用户输入的验证)当比较时,例如抛出异常或使用特殊返回值来表示失败。

0

看看FluentValidation(http://fluentvalidation.codeplex.com/)。我想这就是你要找的。

有了它,您可以定义您的验证规则并调用其验证方法。它将返回潜在验证错误的完整列表,而不会导致代码中出现异常。

+0

非常感谢,但我希望能得到一些关于最佳实践的指导,以及其他人如何处理这个问题,所以我可以自己做。这似乎是一个非常常见的数据输入结构... – rune711

+0

虽然流畅的验证确实显得很刺耳。 – rune711

+0

=)这是一个很好的框架,你会遇到的许多验证框架/模式将非常相似。 – ohiodoug