Php 为什么将有状态对象传递给构造函数是件坏事?

Php 为什么将有状态对象传递给构造函数是件坏事?,php,oop,solid-principles,Php,Oop,Solid Principles,根据我的直觉,通过向对象的构造函数传递有状态对象来实例化对象是一种不好的做法。以这段代码为例: class MathValues { private $x; public function __construct($x, $y) { $this->x = $x; $this->y = $y; } public function getX() { return $this->x;

根据我的直觉,通过向对象的构造函数传递有状态对象来实例化对象是一种不好的做法。以这段代码为例:

class MathValues
{
    private $x;

    public function __construct($x, $y)
    {
        $this->x = $x;
        $this->y = $y;
    }

    public function getX()
    {
        return $this->x;
    }

    public function getY()
    {
        return $this->y;
    }
}

class MathCalculator
{
    private $mathValues;

    public function __construct(MathValues $class)
    {
        $this->mathValues = $class;
    }

    public function calculateMultiplication()
    {
        return $this->mathValues->getX() * $this->mathValues->getY();
    }
}

$mathValues = new MathValues(2,5);

$mathCalculator = new MathCalculator($mathValues);
$someValue = $mathCalculator->calculateMultiplication();
现在,我已经做了很长一段时间的web开发人员,直到最近,我才开始使用OOP范式进行开发,遵循(尽我所能)坚实的原则、面向服务的体系结构等。还有一段时间,我一直在使用Symfony2/3框架进行开发。我在那里看到的一切(包括Symfony的服务容器)都说构造函数应该用来传递其他服务(无状态实例),但我一生都找不到什么原则说不应该将有状态对象传递给构造函数

所以我的问题是在标题中-什么原则说将有状态对象传递给构造函数是件坏事

更新

我的问题似乎不够清楚,所以我更新了我的示例。在本例中,问题和解决方案是明确的:每次,当我需要乘法时,我需要创建2个类的2个实例。相反,我可以创建一个服务MathCalculator,并将两个参数传递给它—x和y。所以我只需要一个实例来表示我要对其进行数学运算的所有值,以及一个对象来表示我需要对其进行数学运算的每个值(如果需要的话)


更不用说有状态编程是一种糟糕的动态行为,我认为应该将价值不变的对象和根本没有状态的服务分开。

首先,正如您在更新中提到的那样,每次有不同的
MathValues
供其操作时,都要实例化新的
MathCalculator
是不理想的

您需要询问的第一件事是,值
x
y
MathCalculator
方面是否确实具有任何特定于领域的实际关系。如果它们都是用户输入的随机值,那么将它们放在同一个类中是不好的-
S
of
SOLID
表示应该应用单一责任或封装的原则。
MathValues
的一个实例应该有一个值,
y
应该成为
MathValues
的另一个实例,因此在这种情况下,
MathValues
变得多余,您可以只使用一组或一组数字

我怀疑您正在使用
MathValues
作为

否则,如果
x
y
以某种方式相关,并且它们属于同一类,例如地理数据或网格引用,那么您使用
MathValues
所做的就是反模式和违反

您应该将您的业务逻辑放入实体中,以遵守
SOLID
S
——知道如何将x和y相乘的责任属于
MathValues
,因此为了满足单一责任和封装的职责,您应该将该方法重构到该类中


诚然,这是有争议的,因为实际上您的
MathValues
看起来也像一个DDD,在这种情况下,您不希望在其中包含任何逻辑,而是将
MathValues
聚合到一个聚合类中,并将方法放在那里。虽然这是一个你只想在你的域名变得越来越复杂的时候才做出的决定。

在你之后会有一个状态,为什么你认为这是一件坏事?我认为这与Symfony问题没有太大关系。嗯,我认为这是合适的,因为我提到了Symfony,我对它的大部分想法都是基于使用它。。。但我还是删除了它,更重要的是,构造函数中的对象应该与该类具有相同的生命周期。首先,您显然很有知识,您所说的很多事情让我很高兴,因为这意味着有开发人员关心代码的质量:)事实上,您所说的大部分内容我都已经学到了(我已经很久没有发布这个问题了)。但是!我的问题是——“为什么将有状态对象传递给构造函数是件坏事?”-很抱歉,我不确定你是否回答了。没有人说这是错的。事实上,我怀疑是否有任何原则提到构造函数。构造函数只是一个实现细节。这就是为什么我扩大了回答的范围。