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

时间:2011-05-02 19:38:20

标签: oop zend-framework design-patterns value-objects domain-object

通过查看Zend Quickstart教程中的域对象示例以及考虑DAO / VO模式的其他示例,它们似乎都非常相似。

我们可以推断说“价值对象”和“域对象”是一样的吗?

如果没有,请您澄清一下之间的区别?

一个人的功能是什么,如果是另一个人的功能怎么办?

我问这个是因为,两者都是由吸气剂和制定者组成的,仅此而已。看起来,它们的功能相同......

更新

因此,Zend Framework快速教程文档称之为域对象:

 // 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 个答案:

答案 0 :(得分:11)

通常,值对象封装具有值的东西:货币,日期,温度等。它们可能包含值和单位,但它们并不复杂。

域对象可能更复杂(除非它是一个Anemic Domain Object,它是一群假装是域对象的getter和setter),因为它包含域逻辑。

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

发票本身可能会因延迟付款的利率,支持审批流程或支持您的会计系统而变得复杂。

Value Object非常简单,可以在不同的域中重用。域对象为您的实际域建模,通常用于为您的特定业务或域建模,包括您的业务逻辑。

您经常会发现它们之间差别不大的原因是许多开发人员将使用事务脚本/数据传输对象设计,但将其称为域模型。他们将他们的getter和setter集合标记为“域对象”。

答案 1 :(得分:2)

他们可以是同一件事。在许多情况下,他们是。但是:

  • 域对象可以执行业务逻辑(至少根据域驱动设计),值对象不能
  • 域对象具有完整信息,而值对象仅包含与其使用者相关的部分信息。

例如,如果是Invoice域对象,它将与值对象相同,然后您可以为两者使用相同的类 - 它将具有发票号,订购商品,总价

另一方面,User域对象将具有您希望能够在系统中处理的密码字段和电子邮件字段,但您绝不应该发送到其他系统。因此,您需要一个缺少这两个字段的新值对象。

答案 2 :(得分:2)

在之前的回复基础上,我认为他们相同:

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