Есть ли преимущества использования __get / __set вместо традиционных методов получения / установки, кроме меньшего количества кода? - PullRequest
6 голосов
/ 17 июля 2011

из Java, у меня всего несколько визитов в PHP. Глядя на магические методы get и set, мой животик (под влиянием Java) начинает болеть: похоже, что вы обращались к свойствам напрямую (хотя, конечно, вы на самом деле используете __get и __set).

Итак, кроме меньшего количества кода, который вы должны написать, есть ли преимущества использования магических методов получения и установки вместо традиционных методов getX () / setX ()? Должен ли я начать использовать их при кодировании PHP?

Спасибо и всего наилучшего!

Ответы [ 7 ]

2 голосов
/ 17 июля 2011

Единственным преимуществом __get() является возможность меньшего количества кода, но даже в этом случае это не обязательно так. Например, если у вас есть набор из 10 закрытых членов, и вы хотите, чтобы получатель показал 5, вы должны написать __get(), чтобы при вызове одного из псевдо-видимых членов вы отправляли его. В противном случае вы либо выдаете ошибку (которая в противном случае возникнет естественным образом без __get(), либо вернете значение, такое как null, которое на самом деле может оказаться бесполезным.

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

class _ {
   public $_;
}

против

class _ {
   private $_;
   public function get_() {
      return $this->_;
   }
}

Разницы нет.

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

У меня по существу те же аргументы против __set() и сеттеров, но есть одна приятная вещь, которую __set() позволяет вам сделать:

class _ {
   private $_ = array();
   public function __set($key, $val) {
      $this->_[$key] = $val;
   }
}

Это позволяет вам набрать очень хороший $_obj->key = 'val'. Обратите внимание, что нет большой разницы от этого и добавление другого метода, такого как add(), который принимает ключ и значение и делает то же самое, я просто предпочитаю нотацию установки объекта.

1 голос
/ 17 июля 2011

Существует мало различий между методами получения и установки и методами __set() и __get()!это магические методы!__set() используется, когда вы хотите присвоить неопределенное состояние объекту, поэтому __get() также используется для получения значения неопределенного состояния!сеттер и геттер используются для назначения или получения значений определенных состояний

1 голос
/ 17 июля 2011

Преимущества состоят в том, что при рефакторинге прямые назначения / чтения могут обрабатываться без необходимости немедленного изменения всей полной кодовой базы, код может быть несколько короче, и людям легче создавать строки (например:$title="<title>{$obj->title}</title>"; против $title='<title>'.$obj->getTitle().'</title>';.

Однако методы __get & __set могут стать большими и громоздкими довольно быстро, и при правильном и явном кодировании, по моему мнению, лучше использовать явные *Вызывается 1007 * методов, чтобы сделать понятные функции, и незначительное увеличение многословности кода, насколько я считаю, оправдано, поскольку можно легко увидеть, что на самом деле вызывает функцию, а что нет. Возможное исключение может быть, когда высоздание декоратора для другого класса / объекта, но это все.

1 голос
/ 17 июля 2011

__get__ и __set__ являются полностью динамическими.Так, например, вы можете запустить запрос к базе данных, если они вызваны для отложенной загрузки.Конечно, вы могли бы сделать это и с геттерами и сеттерами, но тогда вам придется делать это каждый раз.Вы также можете сделать что-то вроде AOP, потому что каждый вызов свойства передается через один метод.Таким образом, в целом __get__/__set__ предлагает больше гибкости в зависимости от времени, которое они тратят на обработку.С ним можно делать действительно продвинутые / крутые вещи.

0 голосов
/ 08 февраля 2014

Существуют накладные расходы в динамическом программировании (например, использование магических методов). Старый тест: Тест магии

Поскольку PHP является динамическим (а не полностью корпоративным) языком, сокращение строк кода и отсутствие некоторых наносекунд представляется хорошей идеей в многих случаях (для отладки, масштабируемости, уменьшения ошибок и т. д.).

0 голосов
/ 30 июля 2012

При написании getX () / setX () для каждого атрибута, практически говоря, у вас будет как минимум 7 строк кода.Это предполагает, что скобка вашего метода открытия находится в той же строке, что и определение, и вы помещаете в метод только одну строку кода, тогда у вас есть закрывающая скобка на своей собственной строке.

Для нетривиальный объект, умножьте это на 6 (YMMV).Это 42 строки только для доступа к атрибуту / мутации.Это не включает проверку или нормализацию ввода.Для альтернативы, проверьте: https://github.com/metaphp/attributes

0 голосов
/ 17 июля 2011

кроме меньшего количества кода, который вы должны написать, есть ли преимущества использования магических методов getter и setter> вместо традиционных методов getX () / setX ()?Должен ли я начать использовать их при кодировании PHP?

Учитывая, что для написания меньшего количества кода это уже серьезная причина, чтобы начать их использовать.
Другая причина в том, что вы можете добавить общее поведение ко всемваш геттер / сеттер

function __set() {
   //> Do some code in common between all setter

   //> set your var here
}
...