我最近研究了依赖注入设计模式。
class User
{
private $db;
public function __construct(Database $db)
{
$this->$db = $db;
}
}
我不禁想知道这是我在聚合中学到的相同的事情。如果我错了,请纠正我。我知道依赖注入的 目标 和聚合 不同。有什么我想念的吗?
答案 0 :(得分:2)
我不禁想知道这与我在聚合中学到的东西相同
考虑一个Department
类,例如,有Professor
个对象数组作为实例变量。有两种方法可以使用一些Professor
对象初始化教授数组。
Professor
和Department
,在某些不带参数的方法中初始化professors[0]=new Professor("CK");
类中professors[1]=new Professor("MK");
数组的元素。 Professor
类型的数组作为其参数。任何想要实例化Department
的类都必须将Professor
个对象数组传递给构造函数。 聚合:使用选项1或2来定义Department
如何获得其教授并不重要。即使没有部门(假设教授属于多个部门),教授也将继续存在,因此无论教育部门如何获得教授,这都被认为是聚合。
依赖注入如果使用选项2创建Department
实例,则将其称为依赖注入。一个部门需要教授,你通过在Department
课程之外提供它来实现这种依赖。
换句话说,聚合是一种关系类型,可以使用选项1或选项2(或其他选项,例如从数据库中获取教授并填充{{1})来建模在方法内的Professor
中的数组)。依赖注入是设计类的方法,以便可以从类外部提供其依赖项。可以对聚合关系建模以支持依赖注入,但这并不意味着聚合和依赖注入是相同的。
答案 1 :(得分:1)
聚合通常被建模为一对多关系,而且往往意味着部分整体语义。由于这些原因,用户数据库通常不被视为聚合:关系是1:1,用户的概念不一定意味着数据库。
将此与汽车及其车轮的常见聚合示例进行对比。有一对多的关系,汽车的概念通常意味着它有轮子。
依赖注入可以被认为是创建关系的方式。关系可以是1:1或一对多。它可能意味着某些语义,或不是。 DI的关键特征是User
不能控制DB
的创建,也不会启动它的创建。
实际上,聚合关系通常可以通过依赖注入来创建;但这并不意味着这两个概念是等价的。 DI可以创建其他类型的关系,并且可以在没有DI的情况下创建聚合。
答案 2 :(得分:1)
聚合是一种维护对象之间关联的方法。在描述对象之间构造关系的方式时,可以使用此术语。它是一个域名术语,现实生活中物体之间存在着同样的关系。
依赖注入是一种在对象之间管理依赖关系的方法,以实现松散耦合。可以在聚合中使用相同的技术。但通常,在聚合中,它不是关于耦合,而是关于对象如何相关。这个术语也有现实生活中的类比,但它们主要用来解释什么是控制反转,通常,你的域名没有对应关系。
答案 3 :(得分:1)
聚合是一种对象组合形式。它与依赖注入无关。
另一方面,依赖注入并不是关于对象如何关联,而是如何将其他对象(依赖关系)转换为特定对象。 依赖关系可以是聚合,服务,存储库,验证器,文字......
通常,在强类型语言中, dependencies 作为接口引入,以避免将对象与实现细节耦合。相反,在动态类型语言中,约定和强大的文档可以构建一个良好且紧密耦合的依赖图。
请注意,数据库不能是聚合。并非所有关联都被视为聚合,而您可以考虑注入依赖。
无论如何,你的推理中有一些设计气味:用户不应该依赖数据库,但如果数据层/数据映射层是注入你的用户实体的更好的候选者,您将实施active record pattern之类的内容。
答案 4 :(得分:1)
我决定添加这些要点。
如果我从你的角度思考你应该问这个问题,因为聚合& 依赖注入提升可以放入其他实体的实体,也可以单独工作。
但是有区别。在 聚合 中,您正在使用直接对象。即维持状态,生命周期等的物体。
例: 灯泡&间强>
但是在 依赖注入 中,我们专注于类级别的交互。这与纯OOP实践有些不同。实际上在DI中我们倾向于将 无状态类 (工作者类)注入到其他类中。虽然它们看起来像对象,但它们实际上只是被注入的无状态类。该类的实例也可以独立存在。 DI被广泛用作 Traditional Singleton Pattern 的替代品,因为传统方式有一些负面的副作用。
前:
假设一个名为 StringUtils 的无状态工作者类(不是使用静态方法堆叠的apache)。它可以注入名为 NounUtils , VerbUtils 等的类中。 StringUtils 的实例也可以存在。
希望你有个主意。 :))