【发布时间】:2018-09-13 17:21:39
【问题描述】:
考虑以下类结构:
框架代码(蓝色区域)
- LOG 类 - 简单的日志类。
- DATABASE 类 - 注入 LOG 类。 (比如说,记录错误或 SQL 查询)。
- REDIS 类 - 还会注入 LOG 玻璃。
- 业务逻辑类 - 注入所有上述构造函数。
.
应用代码:(黄色区域):
- 实例化并使用框架代码。
当前的框架构造函数代码是这样的:
class Database{
public function __constuctor (Logger $log, $databaseHost, $databaseUser, $databasePass, $databaseName){...}
}
class Redis{
public function __constuctor (Logger $log, $redisHost, $redisUser, $redisPass){...}
}
class ACME{
public function __constuctor (Database $db, Redis $redis, $otherStuff, ...){...}
}
在应用程序中,我们执行以下操作:
$logger = new Logger();
$db = new Database($logger, 'db_host','db_user','db_user','db_pass');
$redis = new Redis($logger, 'redis_host','redis_user','redis_pass');
$acme = new Acme($db,$redis, ...other_stuf...);
构造函数变得又长又丑,我很想创建一个依赖容器(DI)并将它作为单个构造函数参数传递。 .
考虑原则:“对象不应该知道包含它的依赖容器”,我觉得这样不行,因为这只会用一个新的替换当前的多个依赖项- 依赖容器 (DIC) 本身。
感觉不错的是可以在Application部分使用DIC的注入(图中黄色部分),但是在基础框架代码(蓝色部分)中注入DIC就不行了。
我错了吗?
注入DIC可以吗?
在这里使用服务定位器模式不是更好吗?
【问题讨论】:
-
你试过用谷歌搜索那个主题吗?你不是第一个问这个问题的人
-
是的,尝试了很多。也在这里,在 SO 中。在这种情况下,我发现的建议是:1)将应用程序拆分为更小的部分,以减少构造函数参数长度和依赖关系(不适合我)。 2)使用服务定位器或单例(静态方法) - 由于某种原因也被认为是一种不好的做法。其实大家都推荐使用DI,但是没有人给出一个最佳实践如何DI纠正和处理大量需要注入的引用
-
“大量引用”是什么意思?可能您有一些几乎不违反 SRP 的类,需要拆分成更小、更易于维护且依赖项更少的类?