2014-10-05 4 views
0

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

protected 
    $a = false; 

    public function getA(){ 
    return $this->a; 
    } 

    public function setA($value){ 
    $this->a = (bool)$value; 
    } 

Какая польза от этого и почему бы просто не сделать общественным достоянием?

+1

возможный дубликат (https://stackoverflow.com/questions/1568091/why-use-getters-and-setters) – Boann

+0

Вот отличный ответ: [? Зачем использовать добытчик и сеттер] [1] [1]: http://stackoverflow.com/a/1568230/3916476 – tenhsor

ответ

4

OOP реальный мир сценарий:

Представьте, что вы есть класс Vehicles и у них есть (protected) wheels. У вас разные Vehicles с wheels, но до addWheel до Bike, отличается от addWheel до Aircraft.

Код преимущество:

Использование геттер и сеттер, вы можете использовать typehinting.

Сравните эти отрывки:

class Car { 
    public $wheels; 
} 

$bmw = new Car; 
$bmw->wheels = 'piece of paper'; 

Приведенный выше код позволяет вам добавить что-нибудь в качестве wheel, но вы можете использовать кусок бумаги, как колесо?

Теперь с геттер и сеттер:

class Car { 
    protected wheels; 
    public function __construct() { 
     $this->wheels = new ArrayIterator; 
    } 

    public function addWheel(Wheel $wheel) { 
     $this->wheels->add($wheel); 
     return $this; 
    } 
    public function removeWheel(Wheel $wheel) { 
     $this->wheels->remove($wheel); 
     return $this; 
    } 
} 

class Wheel { 
} 

$bmw = new Car; 
$bmw->addWheel('piece of paper'); // <-- throws an error! 
            // paper cannot be used as a wheel 

$bmw->addWheel(new Wheel); // <-- good :-) 

Больше кода, чтобы быть более простым.Представьте, у вас есть RearWheels и FrontWheels: [? Зачем использовать добытчиками и сеттеров]

class Wheel { 
} 

class FrontWheel extends Wheel { 
} 

class RearWheel extends Wheel { 
} 

class Car { 
    protected wheels; 
    public function __construct() { 
     $this->wheels = new ArrayIterator; 
    } 

    public function addWheel(Wheel $wheel) { 
     // check for already existing Wheels here. 
     // Pseudo Code: 
     if (wheels typeof RearWheel > 2) { 
      throw new Exception('cannot add more than 2 RearWheels to the Car'); 
     } 
     return $this; 
    } 
    public function removeWheel(Wheel $wheel) { 
     $this->wheels->remove($wheel); 
     return $this; 
    } 
} 
2

Он позволяет добавлять пользовательские сеттеры и геттеры на случай, если вы хотите добавить дополнительные функции, а также иногда используется для отслеживания состояния «грязного» (если объект был изменен с момента его загрузки из БД).

Это также связано с тем, что PHP не имеет «родного» синтаксиса для свойств только для чтения.

Дополнение Я didn't вполне получить мою точку через мой оригинальный ответ, что его во многих случаях из-за, как работает PHP.

Рассмотрите этот пример PHP, где мы используем метапрограммирование для динамического вызова настраиваемых настроек.

class Foo { 
    protected $bar; 

    // use some metaprogramming magic to automatically call setter 
    public function __set($key, $val){ 
     $setter = "set".ucfirst($key); 
     if (method_exists($this, $setter)){ 
      $this->$setter($val); 
     } 
     else { 
      throw new Exception("$key value cannot be set, looking for $setter in ".get_class($this)); 
     } 
    } 
    // enforce the Type of bar 
    public function setBar(String $val){ 
     $this->bar = $val; 
    } 
} 

$foo = new Foo(); 
// this should fail 
$foo->bar = 12; 
// Catchable fatal error: Argument 1 passed to Foo::setBar() must be an instance of String, integer given 

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

1

Популярные библиотеки, которые поддерживают свои классы, которые должны быть расширены или унаследованы, защищают их поля. Это концепция ООП, что должна быть абстракция и инкапсуляция с точки зрения данных. Каждому не разрешается напрямую обращаться к данным. Только член класса должен получить доступ к своим данным. Это поля причины, отмеченные как защищенные, так что только объекты наследуемого класса или объекты одного класса должны иметь доступ к данным. Все остальные должны использовать методы получения и установки для получения данных. Хранение кода управляется, чистым и безопасным.

+0

Там нет золотого правила, которое говорит, что все данные, содержащиеся в объекте должен быть защищен или его «плохой» ООП. Его больше связано с тем, как работает объектная модель PHP. Ruby, например, имеет свойство get/set/readonly, а большие библиотеки, такие как Mongoid и OpenRecord, используют общедоступные свойства. – max

+0

извините ActiveRecord, а не OpenRecord – max

+0

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

Смежные вопросы