【发布时间】:2016-07-06 08:49:41
【问题描述】:
首先,做一个简短的介绍,以帮助您了解我的出发点:我不知道如何为这个问题命名,无论是原样还是存储库跟踪更改的工作单位。
我有两个接口,ChangeListener 和 ChangeSubject,它们是耦合的:
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。
【问题讨论】:
-
在这种情况下,您最终会在某处使用
instanceof。为什么要将 UnitOfWork 与业务对象结合起来?业务对象不应该意识到与持久性相关的问题。 -
@SebastianKeßler 您在哪里看到业务对象和持久性之间的依赖关系?它是依赖倒置,持久性从外部作为 ChangeListener 注入,但也可能有其他的,比如跟踪谁做了什么的安全服务(安全术语中的会计)。如果 PHP 支持泛型,
instanceof就没有必要了。 -
很难理解这和 DDD 有什么关系...
-
@AlexeyZimarev 这个问题也被标记为
design patterns和oop。我已将其标记为ddd,因为所涉及的类也是 UOW 和存储库。这意味着在PHP中做DDD的人很可能遇到过这种情况。当然,DDD 不仅仅是在这种情况下所说明的,它是无处不在的语言,它是有界上下文,等等。 -
您误解了工作单元是什么。 UoW 是一组更改,应该存储所有内容或不存储任何内容。在 DB 世界中,它可以由事务来表示。 martinfowler.com/eaaCatalog/unitOfWork.html
标签: php oop design-patterns architecture domain-driven-design