Следует ли избегать использования конструктора для инициализации поля в PHP?

#php #constructor

#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?

Приветствуются любые идеи по теме.

Комментарии:

1. Не уверен, почему кто-то назвал конструкторы в этом смысле, они довольно распространены для выполнения DI. Возможно, они означают, что у вас должны быть отдельные методы для установки значений, но тогда некоторые объекты бессмысленны без этих значений.

2. В C # вы можете использовать шаблон factory, который инкапсулирует «процесс создания», и тогда вам нужно только изменить factory при обновлении constructor. Я не уверен, как это в PHP

Ответ №1:

Распространенный способ написания классов и достижения того же — использовать закрытые поля с получателями / установщиками, а установщики могут связываться (они возвращают $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
  

Комментарии:

1. Спасибо, этот ответ выглядит хорошо, но как вы убедитесь, что требуемые поля были установлены при вызове метода, который в них нуждается?

2. @Florian Ну, вы можете использовать isset() или empty()

Ответ №2:

Я думаю, что это одна из тех тем, которые вы можете обсуждать миллион лет и все еще иметь миллион разных мнений по этому поводу. Поэтому я не буду вдаваться в подробности (также 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;
        }
    }

}