Php DDD:域模型名称空间约定
我正在用PHP编写一个具有域模型的应用程序,不知道应该采用哪种命名约定 假设我有一个Php DDD:域模型名称空间约定,php,namespaces,domain-driven-design,naming-conventions,namespace-organisation,Php,Namespaces,Domain Driven Design,Naming Conventions,Namespace Organisation,我正在用PHP编写一个具有域模型的应用程序,不知道应该采用哪种命名约定 假设我有一个客户,在其聚合根中有一个地址。 我还有一个产品,在其聚合根中有一个选项 我有两个选择: 将聚合根保留在域模型的根: Customer Customer\Address Product Product\Option Pro:我可以在同一名称空间中同时使用Customer和Product Con:客户必须将其自己的地址引用为客户\地址 将同一命名空间中的所有聚合类分组,包括聚合根: Customer\Custome
客户
,在其聚合根中有一个地址
。
我还有一个
产品
,在其聚合根中有一个选项
我有两个选择:
Customer
Customer\Address
Product
Product\Option
Pro:我可以在同一名称空间中同时使用Customer
和Product
Con:
客户
必须将其自己的地址
引用为客户\地址
Customer\Customer
Customer\Address
Product\Product
Product\Option
Pro:客户可以将其地址引用为地址
Con:从我的根域命名空间,我必须引用:
Customer
作为Customer\Customer
Product
asProduct\Product
不久前我写了一个小框架,我选择使用您提出的第一个解决方案 将聚合根保留在域模型的根:
Customer
Customer\Address
Product
Product\Option
为什么?
事实上,我问了自己和你今天问的相同的问题,在与我的团队成员讨论之后,我们一致认为不在名称空间中重复类名更符合逻辑
让我们看看如何用解决方案n°2实例化您的类
Customer\Customer
Customer\Address
Customer
Customer\Address
你必须写:
$customer = new Customer\Customer();
$address = new Customer\Address();
你可以看到重复,对吗?我觉得有点不对劲。
在我看来,这就像写作
$customer->getCustomerId();
为什么在方法名称中重复Customer?我们知道这是客户的id,因为我们使用的是客户对象
该模型的另一个“缺点”是无法使用保留关键字作为类名
例如,使用pear约定,您可以拥有该类
Customer_Abstract
位于Customer/Abstract.php,这对我来说是可以的,但如果您尝试使用名称空间来翻译它,您将拥有
namespace Customer;
class Abstract {}
这会导致致命错误。因此,您必须再次在类名中重复域:
namespace Customer;
class AbstractCustomer {}
$customer = new Customer\AbstractCustomer();
现在让我们看看如何用解决方案n°1实例化您的类
Customer\Customer
Customer\Address
Customer
Customer\Address
你会写:
$customer = new Customer();
$address = new Customer\Address();
我们不再需要重复Customer两次来实例化Customer类。然而,很明显,地址和客户有关
这就是为什么我选择使用这个模型
编辑:也使用这个惯例这是一个有趣的问题。如果能听到其他人是如何解决这个问题的,那就太好了。希望我们很快会看到一些答案,本杰明:-)开始悬赏,希望在这个问题上获得更多的资源!-)我想到的一件事(可能是离题):
名称空间
在项目规模较大和/或有很多人参与其开发/维护时特别有用。DDD
的基本原则是保持一切简单和切中要害,这意味着在应用程序中几乎不存在任何类型的冲突。所以在这种情况下,namespace
真的有必要吗?@yoda:这是一个好问题,但是我们正在开发的应用程序目前由几十个类组成,所以是的,我们真的很高兴有namespace来组织代码!谢谢你的回答。然而,看起来ZF2实际上使用了完全相反的方法:Zend\Form\Form
,Zend\Mail\Mail
,等等。它们旨在将每个组件打包到一个目录中。你说得对。我没有看所有的代码。我看到了Zend\Controller\Router,Zend\Controller\Router\Route,我没有进一步看。我的错。好吧,我想我们会有更多关于这个问题的阅读,但这可能意味着这只是个人偏好的问题,而不是“最佳实践”。最后,我们将只把聚合根放在域模型名称空间的根上,并将其所有子实体放在具有相应名称的名称空间中。如果聚合根是一个抽象类,那么子类化它的具体类也将在子名称空间中。