领域对象和值对象-它们是否相等?

8
通过查看Zend Quickstart教程中域对象的示例以及考虑DAO / VO模式的其他示例,它们似乎非常相似。
我们可以得出这样的结论,即说“值对象”与说“域对象”是相同的吗?
如果不是,请解释它们之间的区别。
其中一个的功能是什么,另一个的功能是什么?
我之所以问这个问题,是因为它们都由getter和setter组成,除此之外没有任何东西。看起来它们执行相同的功能...
更新:
因此,Zend Framework Quick Tutorial文档称其为域对象:
 // application/models/Guestbook.php

    class Application_Model_Guestbook
    {
        protected $_comment;
        protected $_created;
        protected $_email;
        protected $_id;

        public function __construct(array $options = null)
        {
            if (is_array($options)) {
                $this->setOptions($options);
            }
        }

        public function __set($name, $value)
        {
            $method = 'set' . $name;
            if (('mapper' == $name) || !method_exists($this, $method)) {
                throw new Exception('Invalid guestbook property');
            }
            $this->$method($value);
        }

        public function __get($name)
        {
            $method = 'get' . $name;
            if (('mapper' == $name) || !method_exists($this, $method)) {
                throw new Exception('Invalid guestbook property');
            }
            return $this->$method();
        }

        public function setOptions(array $options)
        {
            $methods = get_class_methods($this);
            foreach ($options as $key => $value) {
                $method = 'set' . ucfirst($key);
                if (in_array($method, $methods)) {
                    $this->$method($value);
                }
            }
            return $this;
        }

        public function setComment($text)
        {
            $this->_comment = (string) $text;
            return $this;
        }

        public function getComment()
        {
            return $this->_comment;
        }

        public function setEmail($email)
        {
            $this->_email = (string) $email;
            return $this;
        }

        public function getEmail()
        {
            return $this->_email;
        }

        public function setCreated($ts)
        {
            $this->_created = $ts;
            return $this;
        }

        public function getCreated()
        {
            return $this->_created;
        }

        public function setId($id)
        {
            $this->_id = (int) $id;
            return $this;
        }

        public function getId()
        {
            return $this->_id;
        }
    }

1) 严格来说,我们面对的是“贫血领域对象”吗?

2) 它之所以被称为“领域对象”,仅仅是因为它包含了领域逻辑吗?

3) 如果是这样的话,那么像findBookByAuthor()这样的方法所在的映射器也在处理领域逻辑,对吗?它们也可以被视为领域对象吗?

非常感谢。

3个回答

13

一般来说,值对象封装的是具有价值的东西:货币、日期、温度等。它们可以包含值和单位,但不复杂。

领域对象可能更加复杂(除非它是贫血领域对象,这是一堆getter和setter假装成领域对象),因为它包含领域逻辑。

例如,您可能有一个发票领域对象,其中包含许多发票行(每个发票条目都有一行),每个发票行可能有净金额、税额和一个发票条目。金额和可能的发票条目通常是值对象,并且相当简单。

发票本身可能会复杂,包括滞纳金利率、支持审批流程或支持会计系统。

值对象足够简单,可在不同领域中重复使用。领域对象对实际领域进行建模,通常编写以模型化特定的业务或领域,包括业务逻辑。

你经常看到它们之间的区别很小的原因是许多开发人员将事务脚本/数据传输对象设计用作领域模型,但称其为领域对象。他们将它们的getter和setter集合标记为“领域对象”。


当然,我是在泛型设计模式的意义上说话。如果你所处的社区对这些术语有不同的定义,那么情况可能会有所不同。 - Terry Wilcox
除非他们在表达领域模型仅是MVC中的“模型”,与给定领域相关,否则我们可以说将“事务脚本/数据传输对象设计”称为“领域模型”是错误的吗? - MEM
1
我认为我们需要区分“Domain Model”和“domain model”或“model”的概念。“Domain Model”是一个具体的设计模式,“domain model”或“model”是一个更一般的术语。您可以在不使用“Domain Model”的情况下对您的域进行建模。MVC中的M可以是一个“Domain Model”,但也可能只是一个“domain model”(或对象模型等)。 - Terry Wilcox

3

在之前的回答基础上,我认为它们并不相同:

  1. 领域对象可以包含业务逻辑。它们代表问题空间中的实体,其属性值可能会更改,并由唯一ID标识。
  2. 根据四人帮的说法,值对象是不可变的。这样的对象不是由任何ID标识的,而是由它们的值标识。

2
他们可以是同一件事情。在许多情况下,它们确实是相同的。然而:
- 域对象可以执行业务逻辑(至少按照领域驱动设计),而值对象不能。 - 域对象拥有所有信息,而值对象仅持有对其使用者相关的部分信息。
例如,在发票域对象的情况下,它将与值对象相同,然后您可以同时使用相同的类 - 它将具有发票号码、订购项目和总价。
另一方面,用户域对象将具有密码字段和电子邮件字段,您希望能够在系统内处理这些字段,但不应发送到其他系统。因此,您需要一个新的值对象,缺少这两个字段。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接