rebelcode/entities

用于处理无类实体的轻量级库。

dev-master 2020-03-13 13:34 UTC

This package is auto-updated.

Last update: 2024-09-13 23:26:40 UTC


README

用于处理无类实体的轻量级库,易于扩展。

本包旨在为灵活的实体提供强大的解决方案,当关联数组不足以表示实体时使用。在这种情况下,实体是一个不由自己的类或接口表示的对象。

我们使用实体的主要用例是允许第三方代码扩展我们的对象的数据和行为,而无需引入扩展类和接口,这会带来其他复杂性。另一方面,使用类似哈希表的数据结构而不是正式对象意味着我们的对象没有需要遵守的合同,无论是接口还是其他。

设计

实体是哈希表结构,这意味着数据是通过键从实体中读取的。

在核心上,该系统使用存储来运行,这是一个对数据库、文件系统、内存、远程API等存储系统的简单抽象。

interface StoreInterface
{
    public function get($key) : mixed;
    public function has($key) : bool;
    public function set(array $data) : StoreInterface;
}

使用属性读取存储,属性代表实体的键。属性与任何实体实例无关;相反,它们在读取和写入调用期间接收实体实例。应注意的是,属性不执行任何实际的写入,而是返回一个“部分提交”的关联数组。

interface PropertyInterface
{
    public function getValue($entity) : mixed;
    public function setValue($entity, $value) : array;
}

模式是一个提供数据的对象,公开了属性及其对应默认值的映射。在这个系统中,模式代表“合同”。当实体使用模式时,它必须提供对模式给出的所有属性的访问,并在可能失败的地方使用默认值。

interface SchemaInterface
{
    public function getProperties() : array;
    public function getDefaults() : array;
}

最后,实体。实体公开了一个类似于存储的API,但有一些新增功能。

interface EntityInterface
{
    public function get($key) : mixed;
    public function set(array $data) : EntityInterface;
    public function getStore() : StoreInterface;
    public function getSchema() : SchemaInterface;
    public function export() : array;
}

首先,公开存储以允许消费代码访问原始数据(例如,属性通常需要存储进行读取)。

还公开了模式,以便消费代码了解可以访问哪些键,甚至执行类型检查。`export()`方法允许实体被简化为数组,以便消费代码可能需要转储整个实体(例如,REST API端点),而不引入迭代器机制。

结果是,一个相当清晰地分离关注点的系统。

  • 属性是可重用的读写对象,可以将原始数据转换为预期的形式,反之亦然。
  • 模式将属性组合在一起以表示实体类型,与存储无关。
  • 存储为任何形式的存储提供了一个简单的抽象API。
  • 实体与其实体的模式或存储实现无关。

通过这种设计,模式取代了传统的类和接口组合,用于对象合同。因为它们没有对实体存储的了解,所以相同的模式可以与任何存储系统结合使用;数据库、远程Web API、文件系统或内存数组。

示例用法

class UserSchema implements SchemaInterface {
    public function getProperties() {
        return [
            'id' => new SimpleProperty('user_id'),
            'username' => new SimpleProperty('user_name'),
            'fullname' => new ConcatProperty(['first_name', 'last_name']),
        ];
    }

    public function getDefaults() {
        return [
            'id' => 0,
            'username' => '',
            'fullname' => '',
        ];
    }
}

$schema = new UserSchema();

// FROM A DATABASE
$store = $someDb->getUser(123);
$entity = new Entity($schema, $store);

// FROM AN ARRAY
$store = new ArrayStore([
    'user_id' => 123,
    'user_name' => 'foo',
    'first_name' => 'Foo',
    'last_name' => 'Bar',
]);
$entity = new Entity($schema, $store);