Если мы говорим строго о PHP здесь, а не о C #, Java и т. Д. (Где компилятор будет оптимизировать эти вещи), я считаю, что методы получения и установки являются пустой тратой ресурсов, где вам просто необходимо указать значение прокси личное поле и больше ничего не делать.
В моей настройке я создал два дрянных класса, один с пятью закрытыми полями, инкапсулированными пятью парами получателей / установщиков, проксирующими поле (которое выглядело почти точно как java-код, как ни странно), а другой с пятью открытые поля и вызывается memory_get_usage () в конце после создания экземпляра. Скрипт с геттером / сеттером использовал 59708 байт памяти, а скрипт с открытыми полями использовал 49244 байта.
В контексте библиотеки классов любого значительного размера, такой как структура веб-сайта, эти бесполезные методы получения и установки могут добавить к ОГРОМНОЙ черной дыре для памяти. Я разрабатывал фреймворк для своего работодателя на PHP (их выбор, а не мой. Я бы не использовал его для этого, если бы у меня был выбор, но, сказав, что PHP не накладывает на нас каких-либо непреодолимых ограничений) и когда я произвел рефакторинг библиотека классов для использования открытых полей вместо геттеров / сеттеров, весь шебанг в итоге использовал на 25% меньше памяти на запрос как минимум.
Магические методы __get (), __set () и __call () действительно великолепны для обработки изменений интерфейса. Когда вам нужно перенести поле в метод получения / установки (или метод получения / установки в поле), они могут сделать процесс прозрачным для любого зависимого кода. В интерпретируемом языке немного сложнее найти все варианты использования поля или метода даже при достаточно хорошей поддержке чувствительности кода, предоставляемой Eclipse PDT или Netbeans, поэтому магические методы полезны для гарантии того, что старый интерфейс все еще делегирует новому функциональность.
Скажем, у нас есть объект, который был разработан с использованием полей вместо геттеров / сеттеров, и мы хотим переименовать поле с именем 'field' в 'fieldWithBetterName', потому что 'field' было неуместным или больше не описывал использование точно, или было просто неправильно. И скажем, мы хотели изменить поле с именем 'field2', чтобы лениво загружать его значение из базы данных, потому что оно изначально не известно с использованием геттера ...
class Test extends Object {
public $field;
public $field2;
}
становится
class Test extends Object {
public $fieldWithBetterName = "LA DI DA";
private $_field2;
public function getField2() {
if ($this->_field2 == null) {
$this->_field2 = CrapDbLayer::getSomething($this->fieldWithBetterName);
}
return $this->_field2;
}
public function __get($name) {
if ($name == 'field')) {
Logger::log("use of deprecated property... blah blah blah\n".DebugUtils::printBacktrace());
return $this->fieldWithBetterName;
}
elseif ($name == 'field2') {
Logger::log("use of deprecated property... blah blah blah\n".DebugUtils::printBacktrace());
return $this->getField2();
}
else return parent::__get($name);
}
}
$t = new Test;
echo $t->field;
echo $t->field2;
(Как примечание: этот бит 'extends Object' - это просто базовый класс, который я использую практически для всего, что имеет объявление __get () и __set (), которое выдает исключение при обращении к необъявленным полям)
Вы можете вернуться назад с помощью __call (). Этот пример довольно хрупкий, но его не сложно убрать:
class Test extends Object {
public $field2;
public function __call($name, $args) {
if (strpos($name, 'get')===0) {
$field = lcfirst($name); // cheating, i know. php 5.3 or greater. not hard to do without it though.
return $this->$field;
}
parent::__call($name, $args);
}
}
Методы получения и установки в PHP хороши, если установщик должен что-то делать, или если получатель должен что-то загружать, или гарантировать, что что-то создано, или что-то еще, но они не нужны и расточительны, если они ничего не делают кроме прокси поля, особенно с несколькими методами, подобными приведенным выше, для управления изменениями интерфейса.