将全局数据库连接传递到模型的每个函数有什么好处?
What are the advantages to passing a global DB connection into each function of a model?
我正在使用一个较旧的代码库,该代码库将数据库连接传递给每个 class 模型中的大多数函数。数据库连接创建为全局连接并在应用程序中随处传递:
$user = new User();
$user->loadById($db, $userId);
与整个模型继承的单个连接(类似于大多数框架当前的工作方式)相比,我们这样做有什么优势?
任何见解都会很有帮助。
完全披露:
我这样问这个问题是因为我们在工作中就是这样做的。我不喜欢我们绕过数据库连接。我正在尝试寻找这种方法的支持者,看看是否可以改变我的想法。这就是为什么我试图将讨论转移到这次对话的 PRO 方面,而不是因为一个坏问题而被阻止。它奏效了。我没有被禁止,但伟大的 Whosebug 社区没有让我失望。看来我对这个问题的看法并不在意。
主要优点是:更容易。正如,这是最简单的事情,因为结果是,你没有应用程序架构。你从任何地方和任何地方抓取东西,因为你不知道如何以其他方式获得它们,这导致可维护性非常差。猜猜这种代码库在 5 年后会发生什么?大量遗留技术债务,很可能您的开发人员没有使用面向对象编程 - 更有可能将过程代码推入 classes.
我不会费心去解释全局状态,因为程序员已经有了 fantastic answer。一小段摘录:
Very briefly, it makes program state unpredictable.
To elaborate, imagine you have a couple of objects that both use the same global variable. Assuming you're not using a source of randomness anywhere within either module, then the output of a particular method can be predicted (and therefore tested) if the state of the system is known before you execute the method.
However, if a method in one of the objects triggers a side effect which changes the value of the shared global state, then you no longer know what the starting state is when you execute a method in the other object. You can now no longer predict what output you'll get when you execute the method, and therefore you can't test it.
您会发现一些开发人员这样做纯粹是出于懒惰或缺乏对 SOLID 基本概念的知识/理解。如果您访问全局状态(如数据库),那么您目前正在编写的美丽、孤立的 class 理论上可以移交给任何其他开发人员,并且还可以自行测试,现在是 耦合到云中某处的这个物体。
除此之外,你还在骗你的对象API。每个对象都应该通过它的构造函数/方法签名,准确地指定它需要运行的所需外部对象。这允许:
- 您的对象具有最终 API 用途
- 未来的开发人员可以从构造函数/方法签名中确切地看到这个对象需要什么才能发挥作用
- 通过 Dependency Injection 传递的所有内容(基本上是传递参数的时髦词),可以是 'mocked out' 用于可测试性
- 由于第 2 点,开发人员不需要通读您的代码来找出还需要什么其他对象
- 您没有访问可以被其他地方的其他东西更改的东西,这让调试成为一场噩梦
你的代码不应该是脆弱的。您应该完全有信心在庞大的代码库中的某个地方进行更改,而不必担心破坏其他地方的东西。您的单元测试将涵盖这一点。我高度推荐阅读The Clean Coder,因为它详细阐述了其中的一些概念。
AlmaDO 有一张关于 Singletons 的好图片,它们基本上是 return 一个对象的 单个实例 的对象,例如数据库或记录器。所以如果你从它请求一个新的数据库,你要么得到一个新的,要么只取回已经存在的那个。在传统的请求/响应/死上下文中,这是完全没有必要的。如果您有一个 非常 长 运行 过程,也许这可能是必要的,尤其是在其他语言中,但作为 PHP 中的一般经验法则;除非您是 运行 PHP 网络套接字服务器或类似服务器,否则 DI 是实现可维护性的更好方法。
这 完全 与调用 StaticObject::Database
相同 - 可以从任何地方访问的内容。
This 对 PHP 中的单身人士来说是一个非常好的 post,而且根本不需要它们 - post 也有很多有用的进一步向下链接。
基本上-不要偷懒,抓住SOLID。它存在是有原因的,当然也不仅仅是为了 PHP。人们这样做的主要原因是因为他们不了解更多,而且更容易,而且更容易并不总是最好的方法。
此外,还有一些额外的说明。我们没有“模型”。我们有一个模型,它是一个层。这是对 'MVC' 的巨大误解,我们甚至在 PHP ('classical mvc') 中实际上都没有。我们有关注点分离,仅此而已。
您的“模型”很可能是服务、领域对象、实体。 More info关于什么型号
您的用户不应该知道数据库。它应该是一个 Entity。 Active Record Pattern is not the way forward. Take a look at DataMapper。您的 存储库 将使用数据库对象和 return 一个 User
对象数组。同样在上下文中,有权访问数据库的用户是没有意义的。
大多数框架不通过访问实体中的数据库来工作-这不再是PHP 4,它已经取得了进步从那以后很多;-)我高度建议远离CakePHP(无论如何不是 MVC)并看一看在像 Symfony 这样的框架中,它仍然存在缺陷 - 了解您选择的框架的缺陷非常重要
我正在使用一个较旧的代码库,该代码库将数据库连接传递给每个 class 模型中的大多数函数。数据库连接创建为全局连接并在应用程序中随处传递:
$user = new User();
$user->loadById($db, $userId);
与整个模型继承的单个连接(类似于大多数框架当前的工作方式)相比,我们这样做有什么优势?
任何见解都会很有帮助。
完全披露: 我这样问这个问题是因为我们在工作中就是这样做的。我不喜欢我们绕过数据库连接。我正在尝试寻找这种方法的支持者,看看是否可以改变我的想法。这就是为什么我试图将讨论转移到这次对话的 PRO 方面,而不是因为一个坏问题而被阻止。它奏效了。我没有被禁止,但伟大的 Whosebug 社区没有让我失望。看来我对这个问题的看法并不在意。
主要优点是:更容易。正如,这是最简单的事情,因为结果是,你没有应用程序架构。你从任何地方和任何地方抓取东西,因为你不知道如何以其他方式获得它们,这导致可维护性非常差。猜猜这种代码库在 5 年后会发生什么?大量遗留技术债务,很可能您的开发人员没有使用面向对象编程 - 更有可能将过程代码推入 classes.
我不会费心去解释全局状态,因为程序员已经有了 fantastic answer。一小段摘录:
Very briefly, it makes program state unpredictable.
To elaborate, imagine you have a couple of objects that both use the same global variable. Assuming you're not using a source of randomness anywhere within either module, then the output of a particular method can be predicted (and therefore tested) if the state of the system is known before you execute the method.
However, if a method in one of the objects triggers a side effect which changes the value of the shared global state, then you no longer know what the starting state is when you execute a method in the other object. You can now no longer predict what output you'll get when you execute the method, and therefore you can't test it.
您会发现一些开发人员这样做纯粹是出于懒惰或缺乏对 SOLID 基本概念的知识/理解。如果您访问全局状态(如数据库),那么您目前正在编写的美丽、孤立的 class 理论上可以移交给任何其他开发人员,并且还可以自行测试,现在是 耦合到云中某处的这个物体。
除此之外,你还在骗你的对象API。每个对象都应该通过它的构造函数/方法签名,准确地指定它需要运行的所需外部对象。这允许:
- 您的对象具有最终 API 用途
- 未来的开发人员可以从构造函数/方法签名中确切地看到这个对象需要什么才能发挥作用
- 通过 Dependency Injection 传递的所有内容(基本上是传递参数的时髦词),可以是 'mocked out' 用于可测试性
- 由于第 2 点,开发人员不需要通读您的代码来找出还需要什么其他对象
- 您没有访问可以被其他地方的其他东西更改的东西,这让调试成为一场噩梦
你的代码不应该是脆弱的。您应该完全有信心在庞大的代码库中的某个地方进行更改,而不必担心破坏其他地方的东西。您的单元测试将涵盖这一点。我高度推荐阅读The Clean Coder,因为它详细阐述了其中的一些概念。
AlmaDO 有一张关于 Singletons 的好图片,它们基本上是 return 一个对象的 单个实例 的对象,例如数据库或记录器。所以如果你从它请求一个新的数据库,你要么得到一个新的,要么只取回已经存在的那个。在传统的请求/响应/死上下文中,这是完全没有必要的。如果您有一个 非常 长 运行 过程,也许这可能是必要的,尤其是在其他语言中,但作为 PHP 中的一般经验法则;除非您是 运行 PHP 网络套接字服务器或类似服务器,否则 DI 是实现可维护性的更好方法。
这 完全 与调用 StaticObject::Database
相同 - 可以从任何地方访问的内容。
This 对 PHP 中的单身人士来说是一个非常好的 post,而且根本不需要它们 - post 也有很多有用的进一步向下链接。
基本上-不要偷懒,抓住SOLID。它存在是有原因的,当然也不仅仅是为了 PHP。人们这样做的主要原因是因为他们不了解更多,而且更容易,而且更容易并不总是最好的方法。
此外,还有一些额外的说明。我们没有“模型”。我们有一个模型,它是一个层。这是对 'MVC' 的巨大误解,我们甚至在 PHP ('classical mvc') 中实际上都没有。我们有关注点分离,仅此而已。
您的“模型”很可能是服务、领域对象、实体。 More info关于什么型号
您的用户不应该知道数据库。它应该是一个 Entity。 Active Record Pattern is not the way forward. Take a look at DataMapper。您的 存储库 将使用数据库对象和 return 一个
User
对象数组。同样在上下文中,有权访问数据库的用户是没有意义的。大多数框架不通过访问实体中的数据库来工作-这不再是PHP 4,它已经取得了进步从那以后很多;-)我高度建议远离CakePHP(无论如何不是 MVC)并看一看在像 Symfony 这样的框架中,它仍然存在缺陷 - 了解您选择的框架的缺陷非常重要