Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

Публичные свойства, геттеры и сеттеры либо волшебные способы?

Anna | 31.05.2014 | нет комментариев

Как правило, суждения расходятся касательно того, отличной ли практикой является применение публичных свойств в PHP классах либо всё же стоит применять геттеры и сеттеры (и беречь свойства приватными либо защищёнными). Ещё одно, компромиссное суждение, состоит в том, Дабы применять волшебные способы__get() и__set().
У всякого из подходов существуют свои превосходства и недочеты, давайте взглянем на них…

Пример применения публичных свойств:

class Foo 
{
    public $bar;
}

$foo = new Foo();
$foo->bar = 1;
$foo->bar  ;

В данном примере bar является публичным свойством класса Foo. При таком подходе мы можем манипулировать данным свойством как желательно и беречь в нём всякие данные.

Превосходства публичных свойств

  • По сопоставлению с геттерами и сеттерами, необходимо печатать на много поменьше текста!
  • Код выглядит больше читабельным и трудиться с ним проще, чем с вызовами геттеров и сеттеров.
  • Вызов публичного свойства (взамен set либо get) работает стремительней и использует поменьше памяти чем вызов способа, но выгода от этого будет примерно неприметной до тех пор, пока вы не будете вызывать способ уйма раз в длинном цикле.
  • Объекты с публичными свойствами могут применяться в качестве параметров для некоторых PHP функций (таких как http_build_query).

Недочеты публичных свойств

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

Пример применения геттеров и сеттеров:

class Foo
{
    private $bar;

    public function getBar()
    {
        return $this->bar;
    }

    public function setBar($bar)
    {
        $this->bar = $bar;
    }
}

$foo = new Foo();
$foo->setBar(1);
$foo->setBar($foo->getBar()   1);

Качество bar здесь является приватным, в связи с этим, доступ к нему не может быть получен напрямую. Для того, Дабы получить значение свойства, вам придётся применять способ getBar, либо setBar для присвоения свойству значения. Дабы вы могли быть уверенны в том, что входные данные всецело правильны, данные способы могут включать в себя соответствующий функционал для их валидации.

Превосходства геттеров и сеттеров

  • Применяя геттеры и сеттеры вы можете осуществлять контроль за тем, какие именно данные содержатся в свойствах объекта, и отклонять всякие некорректные значения.
  • Так же вы можете осуществлять добавочные операции перед тем, как установить либо получить значение свойства (скажем, если обновление данного свойства должно вызывать некоторое действие, такое как оповещение пользователя).
  • При установке значения, которое является объектом либо массивом, вы можете очевидно указать тип переменной в сигнатуре функции(прим. public function setBar(Bar $bar)). К огромному сожалению, PHP не разрешает проделывать тоже самое с типами int и string!
  • Если значение свойства должно получаться из внешнего источника либо среды исполнения, вы можете применять ленивую загрузку данных — таким образом источники, требуемые для загрузки данных, будут задействованы непринужденно во время приобретения значения свойства. Разумеется, в данном случае необходимо соблюдать осторожность, и не следует получать данные из внешнего источника при всяком обращении к свойству. Будет отменнее сделать одно обращение к базе данных и заполнить значения всех свойств сразу, чем делать это для всякого в отдельности.
  • Вы можете сделать качество доступным только на чтение либо только на запись, путём создания только геттера либо только сеттера.
  • Вы можете добавить геттеры и сеттеры в интерфейс для того, Дабы отобразить их в API.

Недочеты геттеров и сеттеров

  • Для разработчиков, которые применяют прямой доступ к свойствам, геттеры и сеттеры кажутся настоящей головной болью! Для всякого свойства необходимо определить само качество, геттер и сеттер; и для того Дабы применять данное качество в коде, необходимо осуществлять добавочные вызовы способа — гораздо легче написать $foo->bar ; взамен $foo->setBar($foo->getBar() 1);(правда, безусловно, дозволено добавить ещё один способ $foo->incrementBar();)
  • Как теснее отмечалось выше, существуют небольшие добавочные расходы, затрачиваемые на вызов способа.
  • Имена геттеров и сеттеров принято начинать с глаголов get и set, но данные глаголы так же могут применяться и в других способах, которые ни коим образом не относятся к свойствам класса.

Пример применения магических геттеров и сеттеров:


class Foo
{
    protected $bar;

    public function __get($property)
    {
        switch ($property)
        {
            case 'bar':
                return $this->bar;
            //etc.
        }
    }

    public function __set($property, $value)
    {
        switch ($property)
        {
            case 'bar':
                $this->bar = $value;
                break;
            //etc.
        }
    }
}

$foo = new Foo();
$foo->bar = 1;
$foo->bar  ;

В данном случае качество bar не является публичным, впрочем в коде оно применяется так, как если бы было публичным. Когда PHP не может обнаружить соответствующего публичного свойства он вызывает соответствующий волшебный способ (__get() для приобретения значения, __set() для установки значения). Данный подход может показаться золотой серединой, но у него есть значительный недочет (см. недочеты ниже!). Следует также подметить, что __get() и __set() способы НЕ вызываются для публичных свойств, и вызываются в случае, если качество помечено как protected либо private и находится за пределами области видимости, либо если качество не определено.

Превосходства магических геттеров и сеттеров

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

Недочеты магических геттеров и сеттеров

  • Недостатком магических способов является то, что они не делают качество доступным(«видимым»). Для того Дабы применять либо расширить класс, вам нужно «легко знать» какие свойства он содержит. В большинстве случаев это немыслимо (если только вы не один из хардкорных программистов, которые думают что notepad является IDE!), правда бывают случаи, когда упомянутые выше превосходства, перевешивают это лимитация. Как подметил один из комментаторов, данный недочет может быть устранён применением phpDoc тегов @property@property-read, и @property-write. Резко.

Какой подход применять
Видимо, что у геттеров и сеттеров есть ряд значительных превосходств, и некоторые люди считают, что ихстоит применять всё время (исключительно те, у кого прошлое связано с Java!). Но на мой взор, этим они нарушают натуральное становление языка, и их излишняя трудность и детализация принуждают меня трудиться с этим, даже если в этом нет потребности (меня нервирует, когда обыкновенные геттеры и сеттеры НЕ делают ничего, помимо приобретения и установки свойства). В таких случаях я усердствую применять публичные свойства, а геттеры и сеттеры я использую для скептических свойств, которые нужно больше сурово контролировать, либо если в них нужно применять отложенную загрузку данных.

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

Уныло, но, RFC нужный для реализации C# сходственного синтаксиса определения способов доступа к свойствам не набрал нужных две трети голосов: wiki.php.net/rfc/propertygetsetsyntax-v1.2 Вот так!

Источник: programmingmaster.ru

Оставить комментарий
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB