【问题标题】:Logic inside constructor构造函数内部的逻辑
【发布时间】:2016-09-05 19:26:27
【问题描述】:

__constructor 中包含逻辑是个好主意吗?

public class someClass
{
    public function __construct()
    {
        //some logic here
    }

到目前为止,我认为这很好;但是,this reddit comment 则相反。

【问题讨论】:

  • @AbraCadaver 这就是我的想法......如果我没记错上下文,OP 建议不要这样做。
  • "Logic" 可能意味着很多东西。 if(!empty($_POST)) { //do stuff } 是我认为的逻辑。
  • @AbraCadaver 是的,就是这样。

标签: php class oop design-patterns constructor


【解决方案1】:

不,这对于自动化测试来说不是一个好主意。在测试时,您希望能够“模拟”允许您控制逻辑的对象,尤其是在接口方面。因此,如果您将逻辑放在构造函数中,则很难测试,因为您必须使用 real 对象。

这是一个精彩的演讲,其中包含更多关于为什么不将逻辑放入构造函数的详细信息(Misko Hevery 的谷歌技术演讲) https://www.youtube.com/watch?v=RlfLCWKxHJ0

【讨论】:

  • 但是,为了测试你需要DI,DI不仅可以通过__construct实现,还可以通过set方法实现...
  • @VladimirKovpak 我同意,有点同意,我仍然认为这个问题的答案是否定的。虽然将大量逻辑放在构造函数中可能不是最佳实践......肯定是工厂......但不是构造函数。
【解决方案2】:

我认为这个问题有点不清楚,因为我认为 __construct 不是逻辑的坏地方,问题是你在这里有什么样的逻辑?某种逻辑可以放在构造函数中,但另一种逻辑不能出现在构造函数中。例如Symfony Response - 构造函数包含逻辑,但是这个逻辑对于这个对象是必要的,并且这个构造函数不会做一些隐式的动作。此构造函数不会将内容打印到输出或其他内容 - 所以这是一个很好的例子(对我来说)......

此外,了解对象必须做什么也很重要,如果它是不可变对象 - 构造函数可以有一点点不同的视图...

遵循 SOLID 和适当的设计模式也很重要...

【讨论】:

  • 那么,可以放置的逻辑是什么?
【解决方案3】:

正如@Barry wrote,原因之一与单元测试有关,但这只是副作用。

让我们以最坏的情况为例:你有一个“类”,它只有一个构造函数(你可能已经看过这样的例子)。那么......为什么它甚至被写成一个类?你不能改变它的状态,你不能要求它执行任何任务,你也无法检查它是否做了你想要的。您也可以使用线性文件并将其包含在内。这很糟糕

现在举一个更合理的例子:假设你有一个类,它在构造函数中进行了一些验证检查,并在其中建立了一个新的数据库连接。然后它也有一些公共方法来执行各种任务

最明显的问题是“建立一个新的数据库连接”——没有办法从类外影响或阻止这个操作。并且这个新的连接将开始做谁知道什么(可能加载一些配置并试图抛出异常)。它还构成了一个隐藏的依赖关系,如果不检查类的代码,您就没有任何迹象。

代码也存在类似的问题,即对传递的参数进行验证和/或转换。它构成了隐藏的逻辑(因此违反了PoLA。它还使您的类更难扩展,因为您可能希望保留该验证功能的一些,同时替换其他部分。而您不需要没有那个选项。因为每当您创建一个新实例时,所有这些代码都会运行。

底线就是这样 - 构造函数中的逻辑被认为是“代码气味”。这不是致命的罪过(就像在全局变量上使用eval()),但它是糟糕设计的标志。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-09
    • 2019-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多