Php DDD:域模型名称空间约定

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

我正在用PHP编写一个具有域模型的应用程序,不知道应该采用哪种命名约定

假设我有一个
客户
,在其聚合根中有一个
地址

我还有一个
产品
,在其聚合根中有一个
选项

我有两个选择:

  • 将聚合根保留在域模型的根:

    Customer
    Customer\Address
    Product
    Product\Option
    
    Pro:我可以在同一名称空间中同时使用
    Customer
    Product

    Con
    客户
    必须将其自己的
    地址
    引用为
    客户\地址

  • 将同一命名空间中的所有聚合类分组,包括聚合根:

    Customer\Customer
    Customer\Address
    Product\Product
    Product\Option
    
    Pro
    客户可以将其地址引用为
    地址

    Con:从我的根域命名空间,我必须引用:

    • Customer
      作为
      Customer\Customer
    • Product
      as
      Product\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,我没有进一步看。我的错。好吧,我想我们会有更多关于这个问题的阅读,但这可能意味着这只是个人偏好的问题,而不是“最佳实践”。最后,我们将只把聚合根放在域模型名称空间的根上,并将其所有子实体放在具有相应名称的名称空间中。如果聚合根是一个抽象类,那么子类化它的具体类也将在子名称空间中。