Каков наилучший подход для инициализации переменных класса?

Вот два способа инициализировать переменные класса.

1-й метод

class Test {
    private $var1;
    private $var2;

    public function Test($var1,$var1) {
        $this->var1 = $var1;
        $this->var2 = $var2;
    }
}
$objTest = new Test("value1","value2");

2-й метод

class Test {
    private $var1;
    private $var2;

    public function _set($var, $value) {
        $this->$$var = $value
    }
}
$objTest = new Test();
$objTest->_set('var1','value1');
$objTest->_set('var2','value2');

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

5 ответов

Решение

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

Кроме того, смысл инкапсуляции в ООП заключается в том, что внутренняя работа класса не прозрачна для кода вне класса. Ваш второй метод нарушает эту инкапсуляцию и, таким образом, является частью точки ООП, так как код вне класса должен знать о внутренних принципах работы класса, таких как имя переменных. Что произойдет, если вы позже решите изменить имена переменных? Весь код нарушается. Если бы к ним обращались через установщики / получатели, старые функции можно было бы изменить, чтобы отразить изменения внутри класса, но изменить код вне класса было бы сложно. В дополнение к этому, второй метод затрудняет проверку значений.

Вы должны использовать первый метод, особенно если для работы необходима установка переменных класса. Однако, если вы чувствуете, что некоторые значения по умолчанию могут быть разрешены для атрибутов, вы можете просто воспользоваться значениями аргументов по умолчанию PHP, такими как:

class Test {
    private $var1;
    private $var2;

    public function Test($var1 = 'defaultValue', $var1 = 'defaultValue') {
        $this->var1 = $var1;
        $this->var2 = $var2;
    }
}
$objTest = new Test();

В любом случае, если значения должны быть инициализированы кодом, то вы должны обязательно принудительно передать их в конструктор. Если значения по умолчанию разрешены, то либо инициализируйте значения в конструкторе с отдельными установщиками для переменных, либо просто значения аргументов по умолчанию, как в представленном примере. Однако плохой практикой является ожидать, что код установит критические значения через сеттеры после вызова конструктора.

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

Интересно, почему вы определили ваши переменные как частные? Закрытые члены существуют для самого класса, а не для использования через открытый интерфейс. Возможно, он отслеживает какое-то значение, которое может изменить метод магического сеттера (__set) в любое время в программе, как у вас во втором примере. Если вам нужно, чтобы ваши переменные были приватными (для доступа только к классу), тогда используйте функцию конструктора __construct($var1,$var2) или __construct ($ var1 = "defaultvalue", $ var2 = "defaultvalue"), поэтому в соответствии с первым пример.

Это будет зависеть от ваших ожидаемых состояний, которые вы запланировали бы на диаграммах состояния / активности.

надеюсь, это поможет

Как насчет этого

class A{

    public $x;
    public $y;
    function A($var1=10,$var2=15){   //the default value for the class
        $this->x=$var1;  
        $this->y=$var2;

    }
}

$object_of_A= new A(20,30);  //if you do not want to change the default value then
                               //pass no arguments

Я думаю, что вы должны объединить оба метода.

Свойства, которые неизбежны, должны присутствовать в методе конструкции.

Для необязательных свойств вы должны определить значение по умолчанию в конструкции, а затем создать getter / setter.

И вы можете создать несколько методов конструирования, как для базы данных, в общем, у вас есть:

myConstructor($dsn)
myConstructor($dsn, $username, $password)
myConstructor($dsn, $username, $password, $port)
myConstructor($dsn, $username, $password, $port, $options)

Тогда в "нижней" конструкции вы установите $options затем вызвать "верхнюю" конструкцию, которая установит $port и назовем "верхнюю" конструкцию... и т.д...

Другие вопросы по тегам