将数据添加到对象 - 验证“然后”添加,还是在添加时验证?
举个例子,
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()
方法中,您是否在之前验证所有传递的数据是否有效/em> 添加它们,或者您在添加它们时验证?
场景 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,因为如果你抛出了异常,你就不应该继续执行?
我很想知道是否有具体的设计模式可以遵循,或者是否有人们的意见。
谢谢。
Take the following example,
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
}
}
On this class we can add a Cup
using $myObject->addCup()
, but we can also add multiple cups using $myObject->addCups()
, or override any existing cups with $myObject->setCups()
.
My question is, in the addCups()
and setCups()
methods, do you validate all the passed data is valid before adding them, or do you validate as you add them?
Scenario 1, validate before you add:
public function addCups(array $cups) {
foreach($cups as $cup) {
if (!($cup instanceof Cup)) {
throw new InvalidArgumentException();
}
}
foreach($cups as $cup) {
$this->addCup($cup);
}
}
Scenario 2, validate as you add:
public function addCups(array $cups) {
foreach($cups as $cup) {
if (!($cup instanceof Cup)) {
throw new InvalidArgumentException();
}
$this->addCup($cup);
}
}
I appreciate there isn't much difference in the code, but it fundamentally changes how the object adds/sets data. In scenario 1, you can only add new data to the object if all the data you are adding is valid, where as in scenario 2 data will actually be added up to the point of the error.
I personally have been using scenario 1, but I can't help but feel you might as well use scenario 2 because if you've thrown an exception, you shouldn't really be carrying on with the execution anyway?
I'd love to know if there's a concrete design pattern to follow on this, or if not people's opinions.
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
首先检查所有项目。
这允许事务行为,这通常是一件好事。这确保了行为易于理解和调试。
就性能而言,它也是更可取的。
但是,如果您的目标是“尽可能多地完成工作”,请检查每一项并在可能的情况下添加它 - 如果一项失败,只需跳到下一项。不过,这是一个罕见的用例。
Check all items first.
This allows for transactional behavior, which is generally a Good Thing. This ensures the behavior is easy to understand and debug.
Performance wise, it is also preferable.
However, if your goal is to "do as much work as possible", then check each item and add it if possible - if one item fails, just skip over to the next. This is a rare use case, though.
我想说这取决于您是否想将添加“杯子”视为交易。当一个或多个 Cup 失败时,您是否希望添加所有 Cup 都失败,请使用方法 1。否则,请使用方法 2。
据我所知,这两种方法都是可行的,并且都有自己的用例。
I would say it depends on wether or not you want to treat adding of 'Cups' as a transaction or not. Do you want adding of all the Cups to fail when one or several Cup(s) fails, use method 1. Otherwise, method 2.
As far as I know, both methods are viable and have their own use-cases.