应该避免在PHP中使用构造函数进行字段初始化吗?

问题描述

昨天我刚刚与两位同事进行了交谈,他们告诉我,我应该停止在PHP中使用构造函数进行字段初始化。

他们的理由是,如果将在不同的位置创建该类的实例,并且我决定添加一个构造函数参数,则该类实例化的所有位置都需要使用新的参数进行更新。可以这么说,这是紧密的耦合

我对PHP相当陌生,在C#中,我将使用构造函数并执行以下操作:

public class Example 
{
    public int X { get; set;}
    public int Y { get; set;}

    public Example(int x,int y)
    {
        X = x;
        Y = y;
    }

}

现在,我通过重载现有的构造函数添加一个参数:

public class Example 
{
    public int X { get; set;}
    public int Y { get; set;}
    public int Z { get; set;}

    public Example(int x,int y)
    {
        X = x;
        Y = y;
    }

    public Example(int x,int y,int z) : this(x,y)
    {
        Z = z;
    }

}

这样做不需要对现有代码进行任何更改,对吧?

据我所知,PHP没有像C#或Java这样的构造函数重载。那就是为什么要避免在PHP中使用构造函数的原因?

有关该主题的任何想法都将受到赞赏。

解决方法

我认为这是您可以讨论一百万年,但仍然对此有一百种不同看法的主题之一。所以我不会去讨论(SO也不是那个地方)。为了解决该问题,php确实允许使用可为空的参数。您可以使用以下内容:

class Example {

    public $x;
    public $y;
    public $z; 

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

        if ($y) {
            $this->y = $y;
        }

        if ($z) {
            $this->z = $z;
        }
    }

}
,

编写类并实现完全相同的一种常见方法是将私有字段与getter / setter一起使用,并且setter可以链接(它们返回$this

这可以通过以下方式完成:

<?php
class Foo
{
    private $a;
    
    public function GetA() { return $this->a; }
    
    public function SetA($a)
    {
        $this->a = $a;
        
        return $this;
    }
    
    private $b;
    
    public function GetB() { return $this->b; }
    
    public function SetB($b)
    {
        $this->b = $b;
        
        return $this;
    }
    
    private $c;
    
    public function GetC() { return $this->c; }
    
    public function SetC($c)
    {
        $this->c = $c;
        
        return $this;
    }
    
    public function ToString()
    {
        return "{$this->a} {$this->b} {$this->c}" . PHP_EOL;
    }
}

用法

$foo = (new Foo())
        ->SetA("Hello")
        ->SetB("World")
        ->SetC(42);

echo $foo->ToString();

此输出

Hello World 42