7

我遇到了我认为是我的 PHP 应用程序的循环依赖问题。如果这不正确,请告诉我。情况如下:

两个类,LogManager 和 DBSession。

DBSession 用于与数据库交互,LogManager 用于记录到文件。两者都在我的应用程序中广泛使用。创建 DBSession 实例时,必须通过构造函数参数为其提供 LogManager 实例。这是因为 DBSession 有时会将信息记录到文件中,并且会使用 LogManager 实例来执行此操作。

现在,我想扩展 LogManager 以便它也可以记录到数据库表,而不是文本文件。当然,我更喜欢重用现有的类,但我很快意识到这带来了一个有趣的情况。

DBSession 已经需要一个 LogManager 实例来构建。如果我想在 LogManager 中重用 DBSession 类,它现在需要一个 DBSession 实例。我怎样才能满足这两个要求?显然,我的方法一定有问题。

你会建议我如何解决这个问题?

提前谢谢各位。

4

4 回答 4

8

不要扩展 LogManager,让它成为一个聚合类型。并延迟选择要登录的位置,即:

$logManager = new LogManager();
$dbSession = new DbSession($logManager);
$logManager->add(new FileLog($filename) );
$logManager->add(new DBLog($dbSession) );

当然,FileLog 和 DBLog 共享一个通用接口。这是观察者模式的一个应用,其中 add() 是“订阅”操作,FileLog/DBLog 是日志事件的观察者。(通过这种方式,您还可以在许多地方保存日志。)

欧文编辑:调整为 php 语法。

于 2008-10-12T04:11:16.057 回答
2

其中一个对象实际上并不需要另一个:您猜对了,它是 DBSession。修改该对象,以便记录器可以在构造后附加到它。

于 2008-10-12T04:11:25.167 回答
2

为什么需要 LogManager 对象来创建 DbSession 对象,如果它只是有时写入文件?仅在需要时才延迟加载它。另外,在我看来,两者都应该相互独立。每个都可以在需要时实例化另一个。

于 2008-10-12T04:14:28.640 回答
1

也许你可以应用一些模式,比如单例模式,以确保你只有一个 LogManager 类的实例。

于 2008-10-12T04:02:57.603 回答