PHP класс def: отдельные средства доступа / мутаторы или __set () с switch () - PullRequest
8 голосов
/ 07 октября 2009

При определении класса PHP, что является предпочтительным / наилучшей практикой? Есть ли какие-то ключевые различия, которые я упускаю из виду?

Кажется, что было бы проще, лаконичнее и удобнее написать магический метод __set() и поместить в него конструкцию switch() с кейсами для всех закрытых членов, к которым я хочу разрешить доступ. Он не будет вызываться автоматически изнутри класса, но, опять же, не будет setFoo(), поэтому, если я хочу использовать аксессор / мутатор внутри, мне придется явно вызывать метод в любом случае.

Другое отличие состоит в том, что в коде вне класса я всегда мог получить доступ к переменным-членам таким же образом, как и $obj->foo, будь то public (напрямую) или private (используя __set()), вместо использования многих отдельных методов.

Я полагаю, это сводится в основном к эстетическому выбору. Например, если у меня есть адресные данные о покупке, я не хочу иметь 16 или более отдельных методов доступа только для имени, фамилии, адреса1, адреса2, города, штата и т. Д. Каждый для данных доставки и выставления счетов.

Есть ли какие-то ключевые различия, которые я упустил из виду? (Может ли сложная среда IDE отказаться от автозаполнения имени члена вне класса, поскольку оно помечено как личное?) Я в значительной степени ответил на свой оригинальный вопрос? Заранее спасибо за ваш вклад.

Ответы [ 2 ]

7 голосов
/ 07 октября 2009

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

  • Что бы вы ни использовали для документирования своего API (doxygen / PHPdoc / Zend), в сгенерированных документах не будут отображаться элементы, доступные через магические функции.
  • Вы можете документировать средства доступа. Вы действительно должны иметь возможность поставить такую ​​строку в документации: « ВАЖНО! Эта функция подключается к базе данных, это будет очень медленно, используйте otherFunction (), если можете.»
  • Реализация средства доступа легко видна всем. Я бы не хотел вдаваться в подробности магической функции из 200 строк, чтобы проверить, делает ли аксессор что-либо кроме установки / получения значения (вот почему мы пишем аксессоры в конце концов.)
  • Вы уже упоминали об автозаполнении IDE.
  • Функция __get () имеет четко определенный заголовок функции, поэтому вы не сможете создавать методы получения, которые возвращают ссылку, например (что действительно здорово при работе с массивами, т.е. $numbers = &$object->getNumbers(); $numbers[] = 4; - без для справки, вам нужно будет снова вызвать сеттер.)
4 голосов
/ 07 октября 2009

Самое большое различие, которое я вижу, в phpdoc:

  • используя __set, вы не сможете сгенерировать phpdoc для каждого метода доступа
  • phpdoc, используемый в современной среде IDE, это также означает, что вы не получите ни подсказок по типам, ни дополнения кода, если будете использовать магические методы (хотя использование @property может помочь в этом вопросе) .

Personnaly, я бы сам определил методы доступа, даже если это означало бы написать немного больше кода:

  • нет проблем с phpdoc
  • вы можете использовать любые параметры и типы возвращаемых данных, которые вы хотите
  • вы явно указываете, какие методы можно использовать
  • проще использовать конкретный код для каждого объекта, без очень длинного __set метода.

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

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

...