我是一名PHP开发人员,目前我正在与Symfony2合作。
我想提出以下问题:
方法逻辑很简单
<!-- language: php -->
public function isValid()
{
return self::STATUS_ACTIVE == $this->status;
}
通过将它们分开并在它与实体之间应用HAS-A关系,我认为它将更灵活和可维护。我不需要将代码复制到任何需要它的实体,即使将来也是如此。
如果您有经验。你能帮我为这种情况选择合适的模式吗?
答案 0 :(得分:1)
在这些实体之间创建一个has-a关系是没有意义的,因为它们不相关。
然而,代码重复几乎从不合理。我会通过创建一个公共接口来解决它(User
是一个可验证的实体,Customer
是一个可验证的实体)并制作一个特征来封装常见的行为。
创建通用界面:
interface Validatable
{
public function isValid(): bool;
}
创建特征以实现常见行为:
trait HasStatus
{
/**
* @var int
* @ORM\Column(type="integer")
*/
private $status;
public function isValid(): bool
{
return $this->status === EntityStatus::STATUS_ACTIVE;
}
}
让您的实体实现新界面并使用特征来避免重复:
class User implements Validatable {
use HasStatus;
}
并使用它:
/** @var Validatable[] $validatables */
$validatables = [new User(), new Merchant(), new Customer()];
foreach ($validatables as $validatable) {
var_dump($validatable->isValid());
}
为什么我们需要界面?从技术上讲,我们不需要它,但我喜欢包含它,因为它允许引用用户,客户,商家与共同的&#34; Validatable&#34; typehint 和它在代码中传达了你的意图。
答案 1 :(得分:0)
弄乱这个并不是一个好主意,实体有状态值,而setter / getter应该在实体文件声明中。 我理解DRY原则,但在这个级别上做...这是恕我直言,不是一个好主意。
但如果您确定所有人都有状态,那么在单独的文件中使用特征:
trait CheckStatusTrait{
return $this->status;
}
您只需将特质添加到您的课程中:
class User {
use CheckStatusTrait
}
答案 2 :(得分:0)
对于那种简单的代码,可以将它留在每个实体中重复,你可以添加一个带有“isValid”的接口,以便在必要时从外部对待它们。
也许你的代码检查验证会变得更复杂,有一个负责的类是有意义的。 然后你可以创建一个StatusValidator类来检查给定对象的状态是否有效。为这种对象添加一个接口是有意义的,它有一个“getStatus”方法,比如说“getStatusInterface”。之后,您可以注入StatusValidator并在isValid方法中使用它。因为您的对象是实体,所以您需要使用doctrine的postLoad事件来注入StatusValidator。
您也可以通过不注入StatusValidator来执行相同的复杂操作,但是如果具有getStatusInterface的obejct是有效的,请询问StatusValidator。
答案 3 :(得分:0)
感谢大家的支持。我也使用trait来解决代码重复问题。但是,我发现这种特质似乎并不完美。我不得不承认以下缺点:
以上是我的愿景。我只是试图找到一种更好的方法来实现这个问题。我希望它对每个人都有用。我听说过ValueObject,但显然不是很明白。我会试着想出来的!