了解Domain对象+ Data mapper模式?

时间:2011-08-08 20:25:32

标签: php oop

我过去一直在使用各种ORM,并将我的所有逻辑放在我的模型中,不管它的性质如何 - SQL,MongoDB查询&甚至获取远程JSON对象。 但是,当有必要确保松散耦合以实现高水平的可测试性时,很快就会出现这种方法的问题。

今天我读过将模型分为两部分Domain objects& Data mappers
如果我完全理解它,Domain objects完全不知道所使用的存储,而是存在以处理业务逻辑。另一方面,Data mappers负责将Domain objects中的数据集存储到设置数据存储中。

然而,我确实觉得在线找到一个关于如何使用DomainObjects&的一个好的,易于理解的例子有点困难。 DataMappers是一个真实世界的例子。

这个(下面显示的代码)是否适合使用DomainObjects&我的代码中的DataMappers用于存储用户还是我脑子里都弄错了?

$user = new User_DO;
$userSave = new User_DM;
$userSave->store( $user->add(array('name' => 'John Doe')) );

class User_DO {

    function add($array) {
        if(!isset($array['name'])) {
            throw new Exception("Name must be set");
        }

        return $array;

    }

}

class User_DM {

    function store($array) {
        MyDatabase::execute("INSERT INTO...");
    }

}

3 个答案:

答案 0 :(得分:25)

这背后的想法是拥有一个标准对象,它代表现实生活中的当前状态,或者换句话说,在域中。此域模型通常是没有逻辑的数据集合。

class person_DO {
    public $id;
    public $firstname;
    public $lastname;
    public $addresses;
}

加载此域模型的实例(域对象)并通过数据映射器处理持久性 - 例如上述人员的地址可能通过1:n关系位于另一个表格中,如下:

TABLE person {
    id        INTEGER PRIMARY KEY,
    firstname VARCHAR(32),
    lastname  VARCHAR(32)
}

TABLE addresses {
    id INTEGER PRIMARY KEY,
    person_id  INTEGER FOREIGN KEY ON person.id, --Reference on person-row
    street     VARCHAR(64),
    ...
}

person_DO不需要知道这一点,但是datamapper会这样做,因为它必须在加载期间聚合数据并在持久化期间分开:

class person_DM {
    /**
     * @param  [integer] $id
     * @return [person_DO] an instance of a person or null, if no person
     *                     with that id was found.
     */
    public function findById ($id) {...}

    /**
     * @return [array of person_DO]
     */
    public function fetchAll() {...}

    /**
     * persists a person object
     * @param [person_DO] an instance of a person
     */
    public function saveOrUpdate(person_DO $person) {...}
}

为了将不同的部分分离得更多,DataMappers通常使用 DbTable Gateway 或类似的模式来允许使用不同的数据库或类似的操作。这样,我可以有几个具有相同模式的数据库,但是在不同的组织中用相同的代码构建数据仓库,只有不同的数据库对象。

作为一个实际的例子,我建议查看Zend Framework的Quickstart Tutorial,它完全按照我刚才解释过的那样。

答案 1 :(得分:8)

近似的方式,是的。虽然我强烈建议不要重新发明轮子并使用像Doctrine 2.x那样实现这种模式的复杂ORM。您可以查看他们的文档(Chapter 8: Working with objects)来对界面进行采样。

答案 2 :(得分:1)

这是一本关于您感兴趣的主题的好书,您可以在持久性框架章节中找到有关数据Mappers(抽象数据映射器)的信息:

Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and the Unified Process