2010-09-14 3 views
2

Im пытается понять преимущества создания переменной класса private, против общественности. Я понимаю, что getters/setters для доступа/изменения конфиденциальных/защищенных данных, но единственная его цель - «не допустить, чтобы я искал свои данные»? Пример: Я не понимаю, как говорятООП, защищенный против общественности. Когда использовать?

$person->age = x;//bad? 

имеет разный потенциал для опустошения, чем

$person->set_x(x);//reccommended in OOP articles 

ответ

0

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

+0

«Держите других в управлении» - так, когда его только я и небольшой проект, круто. В противном случае, getter() setter() выполняет внутреннюю работу класса? Это консенсус? – jason

+1

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

+1

@jason это не вопрос размера команды. Это вопрос чистой, поддерживаемой, стабильной базы кода. –

13

Это все об инкапсуляции.

Предположим, вы используете $person->age = x. На данный момент все будет хорошо, и предположим, что у вас есть эта линия в 100 местах. Позже выясняется, что вы хотите ограничить age, скажем, цифрами больше 0. При непосредственном доступе к переменной-члену нет никакого способа легко обеспечить это ограничение.

Но предположим, вы изначально писали $person->set_age(x) в этих 100 местах. Теперь вы можете изменить сеттера от

private $_age; 
public void age($new_age) { 
    $this->_age = $new_age; 
} 

в

private $_age; 
public void age($new_age) { 
    if ($new_age > 0) { 
     $this->_age = $new_age; 
    } 
} 

Вы не должны касаться ни одного потребителя метода set_age; изменения «просто работают». Это настоящая красота ООП: вы можете скрыть множество деталей реализации за одним вызовом метода.

Инкапсуляция также может помочь в другом месте: скажите, что вам нужен подкласс Person, который регистрировал каждое изменение возраста. С помощью метода setter это так же просто, как переопределение; с прямым переменным доступом, это будет беспорядок.

+0

Вот почему я <3 SO. Upboat. – jason

+0

Да, причина для геттеров и сеттеров в основном для проверки нового значения, вы не хотите «целого», когда вам нужны «ресурс» или «bool». – RobertPitt

0

Ну, я думаю, что метод set/get может помочь улучшить атрибуты атрибутов, как если бы вы напрямую изменили значение, это может вызвать некоторые проблемы, например. вредны для кода. Я думаю, что set/get предоставляет метод, который пользователь может вызывать, а не напрямую работать с атрибутами.

4

Предоставляя аксессуар (методы setter/getter или используя свойства на поддерживающих их языках, например C#), разработчик может определить более стабильный контракт между классом и его пользователями. Вместо прямого доступа к полю, фактически просматривая или записывая местоположение памяти, пользователь вынужден вызывать метод, который, в свою очередь, может инкапсулировать любую необходимую логику.

В свою очередь, при изменении внутреннего дизайна класса его контракт нужно менять реже. Следовательно, улучшается ремонтопригодность и стабильность кода.

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

Edit:

Кроме того, сеттер и добытчик обычно могут иметь различную видимость (публичный/защищенный/частную), обеспечивающие дополнительное преимущество более-зернистый контроль для чтения/записи в течение заданного значения.

Следовательно, лучше всего избегать публичных полей, где это возможно, и использовать методы и свойства setter/getter.

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

  • Нет связанных вопросов^_^