Страницы

Поиск по вопросам

суббота, 8 февраля 2020 г.

Использование приватных (private) и защищенных (protected) полей

#ооп


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

class SimplePdoWrapper
{
    /** @type PDO */
    protected $pdo;
}


$pdo - это ресурс, через который посылаются запросы к базе данных. Я должен объявлять
его как protected или как private? Как понять, нужно ли предоставлять прямой доступ
к этому полю отнаследованному классу? Я отлично понимаю фразу "closed for modification,
opened for extension", но как только подожу на практике, у меня начинается ступор:
если я скрою эти поля, будет ли это означать ограничение расширяемости?
    


Ответы

Ответ 1



Упрощённо говоря, придерживайтесь следующего правила: объявляйте приватным всё, что можно. Вы не должны оставлять поле или метод доступными наследнику «на всякий случай», вы должны понимать, почему без него наследникам не обойтись. Конечно, «open for extension» — это правильно, но в принципе расширение функциональности должно быть возможно не заглядывая в «грязное бельё» текущей имплементации. Если вы строите иерархию классов, вам придётся для начала её спланировать. Вы должны прикинуть, какие непубличные свойства/методы являются важными для расширения (их должно быть по идее совсем немного), а какие не нужны, порождённый класс вполне может обойтись официальными, публичными методами. Прокрутите в голове несколько вариантов расширения. Возможно, с первого раза получится неоптимально, и придётся пересматривать структуру. С практикой придёт опыт.

Ответ 2



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

Ответ 3



Все, что попадает в public, считается интерфейсом класса, в эту часть попадает все, через что взаимодействует класс с внешним миром. Все, что относится к внутренней работе класса, помещаем в private секцию и обеспечиваем инкапсуляцию. Если вы знаете, что класс будет унаследован потомком и ему нужен доступ к private секции, "суем" это в protected. Я так всегда делал, и проблем не было.

Комментариев нет:

Отправить комментарий