Преимущество / недостаток частных переменных? - PullRequest
7 голосов
/ 05 июня 2011

Я привык делать почти все свои переменные класса закрытыми и создавать «упаковочные» функции, которые их получают / устанавливают:

class Something{
  private $var;

  function getVar(){
    $return $this->var;
  }

}

$smth = new Something();
echo $smth->getVar();

Я вижу, что многие люди делают это, поэтому яв конечном итоге сделал то же самое:)

Есть ли какое-то преимущество в их использовании по сравнению с:

class Something{
  public $var;
}
$smth = new Something();
echp $smth->var;

?

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

Так есть ли какие-то другие скрытые преимущества, которые я пропустил с закрытыми переменными?

Ответы [ 5 ]

4 голосов
/ 05 июня 2011

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

3 голосов
/ 05 июня 2011

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

Причина, по которой было бы целесообразно использовать «геттеры» и «сеттеры», заключается в том, что вы хотите контролировать, когда кто-то получает доступ к данным.

В качестве примера, скажем, вы получили это:

public setBirthday($date)

Затем вы можете убедиться, что дата, переданная этому установщику, является действительной датой рождения.

Но вы не сможете, если просто объявите переменную как public

public $birthday;

На основании комментариев.

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

Это означает, что если механизм внутреннего хранилища изменится с 01.01.1970 на количество секунд, то вам не нужно менять «Внешний API». Причина в том, что вы имеете полный контроль над ним:

public getBirthday() {
  // you can still return a string formatted date, even though your 
  // private variable contains number of seconds from 1/1/1970
}
3 голосов
/ 05 июня 2011

Модификаторы доступа не имеют большого смысла в языках сценариев. Многие современные объектно-ориентированные языки, такие как Python или Javascript, не имеют их.

И распространенность наивных методов получения / установки просто из-за того, что PHP не предоставляет для этого явной конструкции. http://berryllium.nl/2011/02/getters-and-setters-evil-or-necessary-evil/

2 голосов
/ 05 июня 2011

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

Например, предположим, у вас есть класс, который предоставляет расчеты по налогу с продаж. Какой-то объект сервисного обслуживания, в основном. У него есть несколько методов, которые обеспечивают необходимую функциональность.

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

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

Если бы другие классы возились с внутренними компонентами класса, то его повторная реализация может привести к поломке других частей системы.

2 голосов
/ 05 июня 2011

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

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

...