看下面的例子,
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,因为如果你抛出了一个异常,你就不应该继续执行了。
我很想知道是否有一个具体的设计模式可以遵循,或者如果没有人们的意见。
谢谢。
先检查所有项目
允许事务行为,这通常是一件好事。这确保了行为易于理解和调试。
性能方面,它也是可取的。
然而,如果你的目标是"做尽可能多的工作",那么检查每一项,并在可能的情况下添加——如果一项失败,直接跳到下一项。这是一个罕见的用例。
我想说这取决于你是否想把'Cups'的添加作为一个交易。如果您希望在一个或多个杯子失败时,所有杯子的添加都失败,请使用方法1。否则,请执行方法2。
据我所知,这两种方法都是可行的,并且有它们自己的用例。