【问题标题】:How to make a good validation in programming?如何在编程中进行良好的验证?
【发布时间】:2011-09-22 11:46:07
【问题描述】:

这是一个问题,我想开发自己的一套 API,它会与其他人共享,当我开发这个 API 时,我无法确保其他人做正确的事......假设我提供了一个简单的打招呼程序... 在任何错误检查和验证中都会有这样的内容:

function sayHello($yourName){
echo($yourName);
}

那么,有些人可能不知道应该传递什么 $yourName 参数,并包括类型检查,所以我将增强这样的东西......

/**
 * Say hello to someone.
 *
 * @param string $aName
 **/

function sayHello($yourName){

    if (!is_string($aName)) {
        throw new ArgumentException("Type not correct.");
    }

    echo($yourName);
}

好的,我可能有进一步的检查,例如,用户可能传递一个空字符串或很长的字符串给我,所以我也需要避免这种情况,所以我的代码会变成这样:

/**
 * Say hello to someone.
 *
 * @param string $aName
 **/

function sayHello($yourName){

    if (!is_string($yourName)) {
        throw new ArgumentException("Type not correct.");
    }
    if(strlen($yourName)) == 0 || strlen($yourName)) > 100){
        throw new ArgumentException("argument length is invalid.");
    }

    echo($yourName);
}

好吧,即使是最坏的情况,我的函数中有一些业务逻辑,例如,我的函数只允许英文名称,所以,我会有一些更复杂的东西:

/**
 * Say hello to someone.
 *
 * @param string $aName
 **/

function sayHello($yourName){

    if (!is_string($yourName)) {
        throw new ArgumentException("Type not correct.");
    }
    if(strlen($yourName)) == 0 || strlen($yourName)) > 100){
        throw new ArgumentException("argument length is invalid.");
    }
    if(!isEnglishName($yourName)){
        throw new ArgumentException("argument business logic is wrong.");
    }

    echo($yourName);
}

如你所见,只有这个简单的sayHello程序可以从3行代码变得更多,它只是一个简单的功能,考虑到我更复杂的逻辑,我怎样才能简化这个过程?我可以采取什么样的策略?谢谢你。

【问题讨论】:

  • 我不确定问题出在哪里?
  • 我想问题是:处理不断增长的验证需求的最佳方式是什么?他可能需要某种验证框架。
  • 用相关的编程语言标记问题总是有帮助的。

标签: php validation error-handling


【解决方案1】:

绝妙的例子!

简而言之 - 不要验证任何东西,这不值得再费力气。

  • 您必须编写它们 - 这很难(3 条规则,而且可能更糟)
  • 它们通常在不同的地方重复(sayHello、setDefaultHello 等) - 因为您没有正确的类型(名称),您仍然只是“限制”字符串。
  • 您必须抛出异常 - 但哪个?

我知道这听起来有多糟糕(我完全无视接触设计,我有多糟糕!),但是:

  • 无论如何,限制输入参数有什么意义?
  • 您真的要禁止传递对象吗?
  • 你的代码是关于“做”还是“限制”?专注于您的目标 - 必须做什么,而不是如何做,而不是何时做。
  • 哪个版本更易读?有或没有验证?

尤其是最后一个应该很有说服力。

总结:

  • 您可以引入 Name 类(以及适用于所有类型的许多其他类)
  • 或者你可以进入duck-typing

我建议后一种。如果您对此还没有意见,请尝试一下,您总是可以回到按合同设计的。只是永远不要将它们混合在一起。

【讨论】:

    【解决方案2】:

    至于处理用户输入,现代网络框架允许验证所有网络表单。这是一个示例(不是取自任何特定框架):

    $validation()->item('name')->add_rule(array('required', 'min_length[2]','max_length[20]' 'is_english', 'is_string'));
    

    您会看到,验证仍然存在,但代码已被抽象出来并集中在其他一些类中,您可以在其中重用功能。

    那么,您只需配置表单,而不是到处复制代码。

    【讨论】:

      【解决方案3】:

      从逻辑上讲,您可能不会简化流程。

      您可以将名称验证放在函数中,以使顶级代码更易于遵循,但您必须在某处进行这些验证。在用户输入$yourName 的情况下尤其如此,在您的示例中可能是这样。

      考虑与此要求类似:您必须检查您调用的每个函数是否返回错误。这里没有什么不同。

      你真的别无选择:如果你没有检查任何函数的错误,你已经在你的程序中放置了一个定时炸弹。此处也是如此:您必须验证函数输入。

      令人沮丧的是,参数验证需要的代码与函数的核心操作一样多。但事实就是这样。没有办法解决它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-04-02
        • 2019-10-17
        • 1970-01-01
        • 2013-09-11
        • 1970-01-01
        • 2018-06-26
        • 2022-06-30
        • 1970-01-01
        相关资源
        最近更新 更多