Какой подход лучше инициализировать свойства php? - PullRequest
13 голосов
/ 16 марта 2011

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

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 ]

13 голосов
/ 16 марта 2011

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

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

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

class Test {
    private $var1;
    private $var2;

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

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

7 голосов
/ 16 марта 2011

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

1 голос
/ 18 сентября 2011

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

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

Надежда, которая помогает

0 голосов
/ 16 марта 2011

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

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
0 голосов
/ 16 марта 2011

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

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

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

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

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

Затем в конструкции "bottom" вы установите1010 *, затем вызовите "верхнюю" конструкцию, которая установит $port и будет вызывать "верхнюю" конструкцию ... и т.д ...

...