magomogo/domain-model

实现特定领域模型持久化的方法

v3.0.0 2023-03-28 06:20 UTC

README

Build Status

简介

  • 我不喜欢ActiveRecord,因为它与数据库的紧密耦合,
  • 我对数据映射器也不太舒服,因为映射器会破坏模型封装,
  • 我喜欢将“状态”与逻辑分开保存的想法。

这是方法

概念

为了实现一个实体,应该创建两个类:模型属性。模型类只包含领域特定逻辑。所有应该持久化的状态都位于属性中。模型聚合了其属性

class Model implements ModelInterface
{
    /**
     * @var Properties
     */
    private $properties;

    public function __construct($properties)
    {
         $this->properties = $properties;
    }
}

这个库负责处理属性,所有其公共字段以及关系都可以在容器中保存/加载。目前有SqlDb、CouchDb和Memory容器。

建议声明模型构造函数签名,不允许创建从业务逻辑角度来看没有意义的实例。

$person = new Person\Model($propertiesBag);
$employee = new Employee\Model($company, $propertiesBag);

来源:Person\Model | Employee\Model

明显的职责

为了实现持久性,我们不需要存储模型,而是需要存储其属性。

// save/update
$dbContainer = new Persisted\Container\SqlDb($connection);
$person->save($dbContainer);

// load
$persistedPerson = Person\Model::load($dbContainer, $id);

来源:Persisted\Container\SqlDb

使用“编辑器”处理用户输入,编辑器类似于容器。

$editor = new ProfileEditor($person);
// validation here
$editor->edit($userInput);

$editedPerson = Person\Model::load($editor);
$editedPerson->save($dbContainer);

不同类型的对象关系之间有强的分离

例如,人员的属性可以聚合联系信息,它与人员一起保存和更新

$contactInfoModel = new ContactInfo\Model($contactInfoProperties);

$personProperties = array(
    'name' => 'John',
    'contactInfo => $contactInfoModel
);

另一方面,有一个人在公司工作。这些对象通过外键连接,并且分别创建/更新。

$company->save($dbContainer);
$employee = new Employee\Model($company, $employeeProperties);

// this won't update the company, but create one-to-many reference company -> person in the container
$employee->save($dbContainer);

一个模型可以有一个与另一个模型连接的模型列表。这种所谓的多对多关系可以通过集合实现。

$collection = new Keymarker\Collection;
$collection['Example'] = new Keymarker\Model(new Keymarker\Properties(array('name' => 'Example'));

示例

查看测试用例以了解推荐用法

...工作进行中...