gpt4 book ai didi

php - 通过构造函数注入(inject)到对象中的依赖项太多了吗?

转载 作者:可可西里 更新时间:2023-11-01 12:17:01 25 4
gpt4 key购买 nike

我正在使用 OO PHP 开发一个社交网络类型的项目,我不想使用现有的框架。做这个项目的主要目的是帮助我了解更多东西。

这个问题更多的是关于依赖注入(inject)。

假设我有这些类(class):

核心类 - 在应用程序中执行操作的一些核心方法
配置类 - 加载站点配置内容
数据库类 - 连接到 mysql 并执行所有与数据库相关的操作
记录器类 - 用于记录错误和调试信息
验证码类 - 用于表单上的验证码
session 类 - 启动 session 并添加、删除、获取要在应用中使用的 session 变量
缓存类 - 类似于 session 类,但用于缓存项(文件缓存、memcache、apc 缓存。有一天我什至可能将我的 session 内容添加到此类中,因为所有这些缓存都可以使用相同类型的方法)

上面的所有类很可能会在我的应用程序中的每个页面加载时使用(我可能错过了一些稍后将添加的类)

现在除了需要注入(inject)到大多数其他类中的上述类之外,我还会有更多的类。我将有一个名为模块的部分,其中包含诸如...

帐户类别 - 创建新用户、验证用户身份、让用户登录和退出应用程序、更新用户设置等等。
用户类 - 显示用户个人资料,显示在线用户,新用户,所有显示网站用户的东西
论坛类 - 将用于论坛部分
博客类 - 用于博客部分
照片类 - 所有与照片相关的东西
评论类 - 处理照片和个人资料的评论

网站的不同部分将有更多此类类型的类(class)。
上面列出的第二组类很可能需要将第一组中的大部分类注入(inject)其中。

那么我应该使用注册表来存储第一组类中的对象,然后将注册表注入(inject)到第二组类中的所有类对象中吗?

或者我应该使用构造函数来加载它们?在这个例子中,将有 7 个对象注入(inject)到其他类中,这看起来很多。我这样做错了吗?

---编辑---
我知道单例模式,但我认为这不是我最好的选择

---编辑 2---
正如一些人提到的那样,需要传递多达 7 个对象确实看起来很多,这就是我寻找建议的原因。对我来说幸运的是,这个项目处于开始阶段,所以现在是改变结构的时候了。

例如我的论坛部分中的类(class)。论坛类需要访问 session 数据、可能的缓存数据、配置对象、数据库对象。我是不是用错了方法?

最佳答案

Or should I use the constructor to load them? In this example there would be like 7 objects to inject into the other classes, that seems like a lot. Am I going about this wrong?

当您开始需要注入(inject)那么多对象时,您需要询问接收它们的对象是否对太多负责。它可以分解成更小的部分吗?

如果实在不行,那就考虑把相关的对象封装在另外一个类中。也许您的 session 、记录器和配置对象可以注入(inject)到 AppApplication 对象中?

编辑:我注意到目前大多数其他答案都在谈论单例。请注意,单例是 DI 的敌人。关于此的精彩 Google 技术演讲 here .

编辑 2:

我所说的封装的意思是,而不是将SessionLoggerConfig等全部注入(inject)到你的Account 类,也许它们应该被注入(inject)到 Application 类中,而 Application 实例可以被注入(inject)到 Account 中。

老实说,这仍然是我正在思考的 DI 的一部分,但我开始看到的是:你应该只将它要注入(inject)的对象注入(inject) Account直接需要操纵。这些对象可能需要操纵其他对象,但 Account 不需要了解它。


通常,您会发现您甚至不需要像您想象的那样多的“层”。如果您发现到处都在注入(inject)东西,请考虑各种重新构建应用程序的方法。让我从模型的 Pylons 文档中提取一段代码:

a = model.Person()
a.name = "Aaa"
a.email = "aaa@example.com"
meta.Session.add(a)

(不用担心 meta.Session...基本上它处理与数据库的交互。)

在这里,我们实例化一个Person,设置它的几个属性,然后保存它。您会注意到 Person 类对数据库一无所知,实际上什至没有 save() 方法。相反,我们将它传递给保存它的数据库类 (meta.Session)。我们已将对 Person 逻辑的关注从数据库代码中分离出来。 meta.Session 可以有多种不同的工作方式,但只要它知道如何读取 Person,就没问题。 (在这种情况下,在应用程序初始化期间,它读取所有应用程序模型的定义)。


好吧,我要总结一下,因为我显然在这里扯了很多。您的问题没有一个“正确”的答案(据我所知,但我不以任何方式宣称自己是 DI 专家)。

是的,注入(inject)多个对象可能表明需要进行一些重组,但您需要考虑一些因素:

  • 接受注入(inject)的对象是否负责太多?可以分离出来吗?
  • 您是否只注入(inject)接收类直接需要使用的对象?
  • 你是不是注入(inject)错了方向;您的 Account 对象可以注入(inject)到您的 Database 而不是相反吗?

关于php - 通过构造函数注入(inject)到对象中的依赖项太多了吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4728795/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com