Я видел много вопросов и ответов о том, использовать ли получатели / установщики или нет (такие как этот популярный), но я также видел два разных стиля получения / установки и очень мало информации о том, какой шаблон предпочтительнее и почему. Первый — использовать 1 метод получения и 1 набор для каждого класса, либо с помощью именованных методов, либо с помощью магических методов (в моих примерах я использую PHP, как то, что я использую изо дня в день, но мой вопрос относится к любому объектно-ориентированному языку).
<?php
class Foo {
private $bar;
private $baz;
public function get($property)
{
if (property_exists($this, $property))
return $this->$property;
}
public function set($property, $value)
{
if (property_exists($this, $property))
$this->$property = $value;
}
}
Второе — использовать 1 метод для каждого свойства.
<?php
class Foo {
private $bar;
private $baz;
public function getBar()
{
return $this->bar;
}
public function setBar($value)
{
$this->bar = $value;
}
public function getBaz()
{
return $this->baz;
}
public function setBaz($value)
{
$this->baz = $value;
}
}
Для жизни я не могу думать ни о какой причине иметь индивидуальные методы для каждого свойства. Даже если вам нужна индивидуальная проверка, вы можете использовать переключатель внутри одного метода, такого как:
<?php
class Foo {
private $bar;
private $baz;
public function get($property)
{
if (property_exists($this, $property))
return $this->$property;
}
public function set($property, $value)
{
if (property_exists($this, $property))
{
switch ($property)
{
case 'bar':
$this->validateBar($value);
break;
case 'baz':
$this->validateBaz($value);
break;
}
$this->$property = $value;
}
}
private function validateBar( & $value)
{
// do some validation...
}
private function validateBaz( & $value)
{
// do some validation...
}
}
Я что-то упускаю или есть необходимость в одном методе для каждого свойства? Это просто хорошая практика использовать один метод получения / установки на класс?
Другой вариант, который был задан, — это использование getsetters, отдельной функции для каждого свойства, чтобы альтернативно получить / установить значение. Я всегда думал, что это нарушает принцип единой ответственности SOLID, но так как он был дан в качестве ответа ниже, я подумал, что обновлю вопрос, чтобы включить его.
Ваш второй пример — обычный способ. Например, Symfony2 фактически создает такие методы получения / установки для объектов ORM.
Еще одно интересное решение, которое дает более тонкий код: Getsetters
Таким образом, вы код, как это (почти как jQuery)
// Setting
$myobject->name('foo')
->age(26);
// Getting
echo $myobject->age();
class Foo {
private $name;
private $age;
public function name($name = null) {
if( ! is_null($name)) {
$this->name = $name;
return $this;
} else {
return $this->name;
}
}
public function age($age = null) {
if( ! is_null($age)) {
$this->age= $age;
return $this;
} else {
return $this->age;
}
}
}
Я бы предложил использовать отдельные методы получения и установки для каждого свойства, так как вы можете использовать методы установки подсказок типа и комментировать docblock возвращаемые значения каждого метода получения, что делает код намного более понятным и легче редактировать при использовании IDE (автозаполнение, декларация и т. д.).
Я за второй более вербальный путь, но я думаю, что это скорее вопрос вкуса.
Преимущества использования геттеров / сеттеров для каждого свойства:
Кроме того, имейте в виду, что если вы всегда используете методы получения / установки, то вы также можете сделать их общедоступными.
В противном случае используйте средства получения / установки для предоставления ограниченного доступа (укажите только получателя) или дополнительного поведения, т.е. setBar($value)
Сделаю $this->value = $value ; updateOtherData();
ИМО, гораздо лучше использовать один геттер & сеттер за собственность. Это способствует правильному использованию объекта, поэтому недопустимый объект нельзя использовать для объекта.
Это также улучшает понимание объекта, так как вы можете легко увидеть, какие свойства доступны для объекта. Также ясно, какие свойства доступны только для чтения (т. Е. У него есть геттер, но нет сеттера).
Рекомендуется использовать функцию setter / getter для каждого свойства, чтобы инкапсулировать каждое поле класса с соответствующими функциями, мы можем использовать один метод setter в конструкторе класса.