如何处理类中的值对象?

时间:2017-08-19 11:31:10

标签: php dependency-injection

当我了解依赖注入时,我会阅读"每一个"应该注入类依赖(让我们暂时忽略接口)

最近转向使用值对象而不是关联数组(在repo'等等)。我读过的大多数教程都在类方法中实例化值对象(没有依赖注入)这不是什么大不了的事。值对象,但为什么这个路径选择vs依赖注入repo构造函数然后克隆空值对象?

我不是在尝试微观优化,主要是努力坚持并学习最佳实践。

我能想到避免克隆路径的唯一原因是构造函数注入值对象数据,但即使这样,克隆后也不能调用构造函数?

例如:

class Repo {
    public function getUser() {
        return new UserValueObject($userDataProvidedByDB);
    }
}

VS

class Repo {

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

    public function getUser() {
        return (clone $this->user)->__construct($userDataProvidedByDB);
    }
}

1 个答案:

答案 0 :(得分:0)

就我在阅读时理解你的问题而言,它更多的是关于实例化对象的问题(不是new - 在课堂内部,更准确地说。)

在很多情况下,在Repository内实例化对象是完全可以接受的。只是因为

  

这不是什么大不了的事情

对于大多数简单的情况,并且当你已经拥有Repository应该返回的类时,将所有那些数据库内容实现为最新的一个(或者当时那个时候)。这使得Repository的测试不会因为要返回的类中的错误而失败,并使这些测试更具功能性/集成而不是单元。

但可能会有更复杂的案例。一个例子可能是类返回时(User,如果提出你的问题)应该有一些丰富的行为,因此使用一些通过构造函数注入的服务。这会迫使Repository对完全不相关的事情有太多的了解,因此它可以实例化User。另一个例子可能是开发人员不了解使用Respository获取的数据进行实例化的内容和方式的情况。

这些情况迫使我们从类中抽象出所有这些无关的知识和功能,并将第三个对象注入到Repository中。所以看起来很像:

interface UserFactoryInterface
{
    public function makeUserFromRawArray();
}


class Repo
{
    private $factory;

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

    public function getUser() {
        return $this->factory->makeUserFromRawArray($userDataProvidedByDB);
    }
}

因此UserFactoryInterface的具体实现知道如何从db创建具有原始数据的User并自行管理其他任何内容。 Repository不依赖于它不应该依赖的东西,它只是从外部获得创建服务。

同样,我相信问题更多的是关于实例化对象和分离关注点的问题,而不是特别关于我Value objects甚至是DTOLocalDTO问题。分别针对您发布的案例。