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

Мне нужен совет / опыт использования общедоступных переменных и частных переменных с методами доступа в php.

например, $ obj-> foo = 'a'; эхо $ obj-> foo;

vs $ obj-> setFoo ('а'); эхо $ obj-> getFoo ();

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

Другой вариант - сохранить переменные в массиве и использовать магические методы (__get / __ set) для доступа к ним - тогда у меня будет простота использования общедоступных переменных с возможностью рефакторинга или методов доступа.

Любой опыт или ссылки на то, что люди делают в мире php.

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


person Yehosef    schedule 13.09.2010    source источник


Ответы (4)


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

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

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

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

echo $obj->setFoo('a');

вместо

$obj->setFoo('a'); echo $obj->getFoo();

если вы включите возврат в свой метод набора

person Mark Baker    schedule 13.09.2010
comment
Я бы подумал, что $ obj- ›setFoo ('a') лучше вернуть $ obj, чтобы я мог связать его. - person Yehosef; 13.09.2010
comment
как насчет простого использования $ obj- ›foo (), где $ obj-› foo () - это получатель, а $ obj- ›foo ('sdf') - установщик? этот подход используется в jquery и, кажется, приводит к относительно чистому интерфейсу - person Yehosef; 13.09.2010
comment
@Yehosef - Лично я всегда сам возвращал объект из установщика, чтобы создать плавный (связанный) интерфейс, я просто предлагал альтернативные варианты ... и нет ничего, что могло бы помешать людям использовать единственный метод get / set (будь то имеет get / set в имени метода - это просто соглашение), которое определяет, является ли он получателем или установщиком, в зависимости от того, передан аргумент или нет. Мой аргумент - причины использовать методы доступа, а не прямой доступ к общедоступным свойствам ... точные нюансы реализации этих методов - совсем другой вопрос. - person Mark Baker; 13.09.2010
comment
@Mark - как насчет того, чтобы сделать это с помощью волшебных методов get / set? Это обеспечивает быстрый способ начать работу / прототип, потому что методы напрямую соответствуют базовой структуре с использованием универсального обработчика, но вы также можете изменить get / set, чтобы действовать по-другому, если реализация должна измениться. Меня больше всего беспокоит метод получения / установки - это просто накладные расходы на написание кода в условиях быстрой разработки. - person Yehosef; 13.09.2010
comment
Это вполне осуществимо с использованием магических методов _get и _set: пару лет назад я провел несколько тестов, когда обнаружил, что магические методы работают немного медленнее, но объем памяти класса уменьшился. Но (на мой взгляд) код легче документировать (с использованием PHPDocumentor) при использовании явных методов get / set ... особенно полезно при написании библиотек OSS или для автозаполнения при кодировании в среде IDE. Я предполагаю, что есть также IDE / инструменты, которые автоматизируют создание методов получения / установки заглушек при загрузке набора свойств (хотя я не мог дать вам никаких ссылок). - person Mark Baker; 13.09.2010
comment
спасибо за ввод - похоже, что могло бы быть хорошим балансом между быстрой разработкой и перспективой, было бы использование $ obj- ›foo () и использование _call для сопоставления этого с $ obj-› foo - я могу начать с минимальные накладные расходы, но когда я обнаруживаю, что $ obj- ›foo действительно должен быть $ obj-› bar, я могу добавить функцию с именем $ obj- ›foo () для получения / установки $ obj-› bar. Затем, если / когда позже появится время заняться документацией, можно заполнить все функции. - person Yehosef; 13.09.2010

сеттеры и геттеры всегда являются лучшим вариантом, потому что они обеспечивают большую стабильность для проверки / очистки.

public function __call($name,$params = array())
{
    if(strstr('set',$name))
    {
    }//returns

    if(strstr('get',$name))
    {
    }//Returns

    if(strstr('run',$name))
    {
    }//Returns
}
person RobertPitt    schedule 13.09.2010

Геттеры / сеттеры возникли в Java. Им нет места в языках сценариев, поэтому они не одобряются, например, в Python и Javascript. Они делают API более громоздким.

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

 function __set($name, $value) {
     if (gettype($value) == $this->_types[$name]) {
          $this->_vars[$name] = $value;
     }
 }   // instead of twenty methods checking the type

Запах кода - реализовать пустые геттеры / сеттеры для создания корпоративного кода. Также нецелесообразно иметь геттеры / сеттеры с побочными эффектами. Всегда используйте реальные методы / сообщения для сложных операций с объектами.

person mario    schedule 13.09.2010
comment
Это интересное различие для языков сценариев - есть ли у вас ссылки, относящиеся к нему? Что вы имеете в виду, имея геттеры / сеттеры с побочными эффектами? - person Yehosef; 13.09.2010

Сеттеры и геттеры - это один из видов реализации инкапсуляции, один из принципов ООП, который гласит, что объект должен быть черным ящиком, просто раскрывающим поведение и его состояние для своих клиентов, но предотвращающим раскрытие его внутреннего. Это позволяет использовать код с низкой связью, поскольку вы можете изменять логику внутри Setter и / или Getter, не затрагивая клиентский код с помощью вашего API.

Как уже говорили многие другие, существуют и другие реализации, такие как магические методы.

person nighter    schedule 17.03.2014