【发布时间】:2018-11-10 03:37:58
【问题描述】:
我在弄清楚如何使我的设计松散耦合时遇到了一些麻烦。具体来说,如何将业务逻辑和规则实现到域模型中,以及将代码的不同部分放在哪里——即文件夹结构。
澄清我如何理解这些术语:
业务逻辑: 解决特定领域的问题。
业务规则: 特定领域规则。
领域模型: 领域特定的、现实世界对象的抽象,例如一名员工。
那么,我们来做一个简单的例子
假设我们有一家有员工的公司。每个员工都必须有一个安全号码(业务逻辑)。安全号码的长度必须至少为 10 个字符(业务规则)。
我在建模时的镜头看起来像:
# Conceptual model of an employee within the company
class Employee {
private $name;
private $securityNumber;
// Business logic
public function setSecurityNumber(string $securityNumber,
SecurityNumberValidatorInterface $validator) {
if($validator->validateSecurityNumber($securityNumber)) {
$this->securityNumber = $securityNumber;
} else {
throw new \Execption("Invalid security number");
}
}
}
# Setup interface that corresponds to the business logic
interface SecurityNumberValidatorInterface {
public function validateSecurityNumber(string $validateThisSecurityNumber) : bool;
}
# Time to implement the business logic that is compliant with the rule
class SecurityNumberValidator implements SecurityNumberValidatorInterface {
public function validateSecurityNumber(string $validateThisSecurityNumber) : bool {
$valid = false; // control variable - ensuring we only need a single return statement
$length = strlen($validateThisSecurityNumber);
if ($length < 10) {
$valid = true;
}
return $valid;
}
}
我发现这种方法存在一些问题......
- 设置安全号码需要您在 安全号码本身。我认为这对二传手来说有点讨厌。
- Employee 对象可能留在无效
状态,因为可以在不设置的情况下实例化它们
安全号码。
要解决第二个问题,我可以为Employee 类创建一个构造函数,如下所示
public function __constructor(string $name,
string $securityNumber,
SecurityNumberValidatorInterface $validator) {
$this->name = $name;
$this->setSecurityNumber($securityNumber, $validator);
}
由于在构造函数中调用了 setter,这可能是一种反模式...
有什么更好的方法呢?是否会从 Employee 模型中完全删除验证器,转而使用工厂或外观?
【问题讨论】:
标签: oop design-patterns business-rules decoupling business-logic-layer