保护私有/受保护方法的输入?

8

通常,所有理智的开发人员都试图保护所有公共方法的输入(转换为正确的类型、验证、消毒等)。

我的问题是:您是否在代码中还验证了传递给受保护/私有方法的参数?在我看来,这并不是必要的,如果您正确地保护了公共方法的参数和外部返回值(其他类、数据库、用户输入等...)。

但我经常遇到框架和应用程序(例如prestashop),其中方法调用、方法体中经常重复验证,并再次对返回值进行保护——我认为这会导致性能损失,并且也是糟糕设计的标志。


除非您使用正则表达式(而您不应该这样做),否则验证不会给您带来太多的性能开销。 - Andy
我曾经见过很糟糕的验证方式,例如在提到的 Prestashop 中,他们在其 ORM 中使用了 isTableOrIdentifier 方法来使用正则表达式检查表/列名称的有效性,并且该方法在同一对象内被调用了数十次(现在想象一下导入数百或数千个对象)。 - ts.
如果您正在进行适当级别的单元测试,那么跳过某些私有成员的某些验证是可以接受的。总会存在风险,但如果您或审核人员检查代码后发现,基于调用公共成员的操作,您的下游假设始终是正确的,则可以接受。 - JoeGeeky
5个回答

3

对于受保护的方法,我认为应该进行验证,因为该方法可能会被覆盖或从其他类中调用,您不能假设该方法的输入有效。如果这是将由其他应用程序使用的组件,则尤其如此。

对于私有方法,我认为这是一种浪费,因为您控制着传递给方法的数据,因此在调用私有方法之前应该对数据进行验证。


2
如果您坚持公共API应该有防御不良参数的实现的观点,您的标准不应该是方法的可见性,而应该是API的用户是否会直接调用该方法(或通过另一个推迟验证的方法间接调用它)。
应该进行验证的方法的示例:
class A {
    protected final function myMethodDefaultImplementation(...) {
        /* subclasses can just call this method in their myMethod implementations */
        /* should do validation */
        ...
    }
    protected abstract myMethod(...);

    public function orderByDate() {
        return $this->orderBy(ORDER_BY_DATE)
    }

    private function orderBy($crit) {
        /* should do validation */
        ...
    }
}

0

确切地说,如果您的应用程序设计得好,那么这是不必要的。


0
我认为方法的类型(public、private、protected)并不重要,你需要在必要时采取适当的预防措施,而不是只看可见性关键字。

-1

只在最后一刻清理输入。我不认为面向对象语义会有任何不同。

例如,如果由于某种原因你不能使用参数化查询或ORM(目前我能想到的唯一一个例子 :),你可以像这样编写函数:

function getname($id) {
    $id = intval($id);
    mysql_query("SELECT * FROM users WHERE id = $id");
    ...
}

现在任何代码都无法调用此函数并导致意外结果。


为什么要投反对票?这就是实际操作。创建一个允许注入 SQL 的 API 毫无意义。更不用说这与已接受的解决方案完全相同了。 - L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接