一般来说,调用者应该保证将格式良好的数据传递给被调用的方法(因此被调用的方法假设数据始终有效)或被调用应该进行数据验证的方法?每种方法的利弊是什么?
this.data = user.input;
// Caller check data
if (!this.data) throw new Exception("Data cannot be null.");
obj.consume(this.data);
public void consume(data)
{
// Called check data
if (!data) throw new Exception("data cannot be null.");
}
答案 0 :(得分:5)
面向外部的(公共,受保护,导出等)方法应该验证他们的输入,因为未知的未来呼叫者可以调用它们。对于面向内部的(私有,内部,内部等)方法,这不是必需的,因为调用者在您的控制之下,可以假设知道它正在做什么。
答案 1 :(得分:0)
一般来说,每种公共方法都应该将其输入作为一个单元进行验证:
public Output Method1(Input1 input1, Input2 input2)
{
if(input1 == null)
throw new NullReferenceException("input1");
if(input1 == null)
throw new NullReferenceException("input2");
// ...
}
你会在每个层中通过例外进行验证,每个层决定是处理该异常还是将其抛出到下一层。
答案 2 :(得分:0)
这个问题无法得到基本的回答。如你所见,这里有两个人已有不同的想法。 (我个人不同意每个公共方法需要检查他们的论点......)所以什么时候检查:如果你的方法得到外部数据,例如通过REST请求。这意味着服务层级别上的所有方法都需要检查它们的参数,并且这些方法是公共的还是包访问或受保护绝对无关紧要。在私人方法上,我会做同样的事情,除非我100%确定其他人已经在更高层次上进行检查。
OTOH如果我制作一个“库”,那么我也可以在文档中指定:确保所有给定的参数都正确,库不执行参数检查。 例如。我有一个用于矩阵和向量计算的库,我当然不会在每个用它们进行计算的方法中执行“vec!= null”和“mat!= null”。我也定义了不要生成vec.length() == mat.height()测试。如果有的话,我会使用断言。(参见例如经典的C字符串操作)。
所以,如果你现在需要一个更多的存储库,没有人会阻止你为库中的每个操作编写一个包装器方法来进行这样的检查。
但是,在必须使对象持久化的环境中,您可能需要注意其内部状态是“正确的”。所以你可能想要更严格的参数处理。然而,在这里,你不能简单地决定:所有公众都进行检查,所有私人都没有。然而,作为开发人员团队,您可以决定:我们总是像这样做,因为我们看到它中的某个值(可能避免单元测试代码中的错误)。