#ооп
Если с использованием публичного типа полей мне все ясно - это то, что объект может предоставить для свободного доступа и модификации, чаще всего это реализуется через геттеры-сеттеры - то разницу между приватными и защищенными я не очень понимаю, точнее, не понимаю, как отделить границы использования одного от другого. Если очень грубо, то класс должен "светить" только необходимые вещи, чтобы не засорять текущую область видимости лишними деталями. И тут я и начинаю плавать: вот, допустим, у меня есть класс, реализующий действия с базой данных: 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. Я так всегда делал, и проблем не было.
Комментариев нет:
Отправить комментарий