2011-04-18 133 views
0

看看下面的例子,将数据添加到对象 - 验证*然后*添加或验证添加?

class Cup {} 

class MyObject { 
    protected $cups = array(); 

    public function addCup(Cup $cup) { 
     if (!in_array($cup, $this->getCups())) { 
      array_push($this->cups, $cup); 
     } 
     return $this; 
    } 

    public function addCups(array $cups) { 
     // Add cups logic, see below 
    } 

    public function getCups() { 
     return $this->cups; 
    } 

    public function setCups(array $cups) { 
     // Set cups logic, see below 
    } 
} 

在这个类,我们可以添加使用$myObject->addCup()一个Cup,但我们也可以使用$myObject->addCups()$myObject->setCups()添加多个杯子,或者重写任何现有的杯子。

我的问题是,在addCups()setCups()方法,你验证所有传入的数据是有效的前加入他们,或者你验证你加入他们吗?

方案1,验证之前添加:

public function addCups(array $cups) { 
    foreach($cups as $cup) { 
     if (!($cup instanceof Cup)) { 
      throw new InvalidArgumentException(); 
     } 
    } 
    foreach($cups as $cup) { 
     $this->addCup($cup); 
    } 
} 

方案2,验证添加:

public function addCups(array $cups) { 
    foreach($cups as $cup) { 
     if (!($cup instanceof Cup)) { 
      throw new InvalidArgumentException(); 
     } 
     $this->addCup($cup); 
    } 
} 

我明白没有太大的区别在代码中,但它从根本上改变了对象如何添加/设置数据。在场景1中,如果要添加的所有数据都是有效的,则只能将新数据添加到对象,而场景2中的数据实际上将添加到错误点。

我个人一直在使用场景1,但是我不禁觉得你可能会使用场景2,因为如果你抛出异常,你不应该继续执行这个执行吗?

我很想知道是否有一个具体的设计模式可以遵循这一点,或者如果没有人的意见。

谢谢。

回答

1

先检查所有项目。

这允许交易行为,这通常是一件好事。这确保了行为易于理解和调试。

表现明智,也是优选的。但是,如果您的目标是“尽可能多地完成工作”,那么请检查每个项目并在可能的情况下添加它 - 如果一个项目失败,则跳过下一个项目。不过,这是一个罕见的用例。

+0

继续PerHolmäng的回答我会同意。我可以想到使用场景2的很少的用例。我现在坚持1,因为它也适合我需要的场景。欢呼为理智检查。 – 2011-04-18 10:56:58

0

我会说这取决于你是否想要把'杯'作为交易加入或不。如果一个或几个杯子失败,您是否希望添加所有杯子失败,请使用方法1.否则,方法2.

据我所知,这两种方法都是可行的并且有它们自己的用例。

+0

这就是最终的问题。在大多数情况下,我会认为它需要事务性。在我的特殊用例中,如果在添加数据时出现问题,整个过程需要停止,因为它在技术上是逻辑异常。 – 2011-04-18 10:53:20