Oop 在松耦合设计中使用基础结构类
我有一个关于松散耦合OOP设计的问题。 考虑一下我们有一个简单的值对象,比如电子邮件Oop 在松耦合设计中使用基础结构类,oop,domain-driven-design,loose-coupling,value-objects,Oop,Domain Driven Design,Loose Coupling,Value Objects,我有一个关于松散耦合OOP设计的问题。 考虑一下我们有一个简单的值对象,比如电子邮件 final class Email { private $_email; public function __construct($email) { self::isValid($email); $this->_email = $email; } public function getEmail() {
final class Email
{
private $_email;
public function __construct($email)
{
self::isValid($email);
$this->_email = $email;
}
public function getEmail()
{
return $this->_email;
}
public static function isValid($email)
{
// some validation logic goes here
return true;
}
}
在我真正实现isValid方法之前,一切都是简单明了的。
我有两个选择:
1) 实现我自己的验证逻辑,它可能非常丑陋,比如:
public static function isValid($email)
{
$v = preg_match(
'/^[-a-z0-9!#$%&\'*+\/\=?^_`{|}~]+(?:\.[-a-z0-9!#$%&\'*+\/\=?^_`{|}~]+)*@(?:[a-z0-9]([-a-z0-9]{0,61}[a-z0-9])?\.)*(?:aero|arpa|asia|biz|cat|com|coop|edu|gov|info|int|jobs|mil|mobi|museum|name|net|org|pro|tel|travel|pro|[a-z][a-z])$/',
$email
);
return $v > 0;
}
2) 使用一些内置框架验证器
public static function isValid($email)
{
$validator = new Zend_Validate_Email(); // tight-coupling detected!
return $validator->isValid($email);
}
我真的不想走第一条路,因为我不想重新发明轮子,也不想重复代码,所以我坚持走第二条路
如果我遵循第二种方法,我就会遇到问题——我的类依赖于另一个框架类
我的实际问题是在简单情况下不使用依赖项注入而直接在实体/值对象中使用低级基础结构类是否可以接受
如果我“正确地”实现这个示例,那么仅仅为了松耦合的目的,代码就会变得更加复杂。我必须创建一个EmailFactory,它将为我的Value Object(Email)类提供一个预配置的EmailValidator实例,该实例将在isValid函数中使用…只要验证函数不需要外部资源,我将直接重用依赖项并避免其注入 域对象封装域规则,并应包含确保这些规则的所有必要信息。它更多地围绕着高内聚性而不是低耦合性进行设计(聚合的概念本身就是减少相互依赖性的一种手段) 示例中的
Email
类应该是电子邮件地址验证的单点故障。如果所有域对象都通过该类验证电子邮件,那么重用现有的框架(甚至第三方)功能是一个实现细节,并且不再是松耦合的问题。如果验证规则发生更改,您将不得不重新实现该功能-使用Zend\u Validate\u Email
或一些自定义代码
将验证逻辑注入实体或值对象会带来很多问题:
- 属于域对象的逻辑将被移动到另一个类
- 向实体中注入服务通常是很困难的
- 仅为
类引入接口违反了EmailValidator
- 在
电子邮件上调用静态
方法是不可能的isValid
只有在验证逻辑需要外部资源的罕见情况下,我才倾向于使用一个带有注入服务的工厂,该工厂在创建域对象时进行验证——但只有在重新考虑域模型的设计之后才进行验证。如果内置框架验证器只是封装逻辑的“功能”,并且不依赖于任何状态或上下文。