编程到界面和观察者模式

时间:2016-03-19 16:13:53

标签: php oop design-patterns architecture domain-driven-design

首先,一个小小的介绍,以帮助您了解我来自哪里:我不知道如何标题这个问题,无论是这样,还是存储库跟踪更改工作单位

我有两个接口ChangeListenerChangeSubject,它们是耦合的:

interface ChangeListener
{
    public function onSubjectChanged(ChangeSubject $subject, array $data);
}
interface ChangeSubject
{
    public function addChangeListener(ChangeListener $listener);
}

我还有一个存储库和一个工作单元(WIP,我将省略一些部分):

interface UnitOfWork extends ChangeSubject
{
    public function commit();
    public function hydrateChange(array $data, ArrayService $arrayService);
}

interface Repository extends ChangeListener
{
    public function commit() : \bool;
    public function commitCount() : \int;
}

现在,在我UnitOfWork的实现中,让我们称之为Book,更确切地说是在方法hydrateChange中,我通知存储库这个变化很容易:

$repository->onSubjectChanged($this, $newHydration);

现在的问题是,在存储库中,我需要知道本书的ID。但是存储库的处理方法收到ChangeSubject,它没有id(Book有)。

如何正确设计这样的系统?

如果PHP有泛型,那就有可能。我不喜欢的hacky解决方案是使用instanceof

enter image description here

1 个答案:

答案 0 :(得分:2)

你误解了一些概念。如果你得到以下权利,你应该回到正轨:

  • 不要在域对象中实现工作单元。工作单元只是一个跟踪变化的技术助手。因此,工作单元引用业务对象,例如注意" ID为32的书已更改",但它与业务对象不同。

  • 为您的汇总类型制作具体的存储库。 BookRepository应包含GetById(BookId)GetByAuthor(Author)等方法。注意:在具有泛型的语言中,可能有机会提取通用部分,但在PHP中,最好使用Book等具体聚合类型。

我建议您了解有关工作单元和存储库模式的更多信息。在尝试使用它们之前,请确保完全理解它们。还要确保您了解不同的存储库变体(例如命令样式存储库与集合样式存储库),以便为您的项目做出明智的决策。