Во многих моих проектах PHP я заканчиваю тем, у кого есть непубличные функции, которые я не намерен распространять.
Лучше ли объявлять их защищенными или частными?
Я могу видеть аргументы в обоих направлениях – сделать их частными – гораздо более консервативный подход, но можно утверждать, что они могут быть защищены позже, если я хочу, чтобы этот метод был расширен, и он дает понять, какие методы расширены базовыми классами.
С другой стороны, использует ли какой-то антисоциальный подход, поскольку он препятствует теоретическому будущему разработчику расширять мой код без изменений?
Мой инстинкт заключается в том, чтобы держать их в секрете, пока вам не нужно, чтобы они были другими.
Было высказано мнение (к сожалению, я упустил ссылку), что частные методы являются антисоциальными, во многом аналогично тому, как сделать их «окончательными», поскольку он довольно диктаторский о том, как люди могут использовать ваш код.
Однако я не убежден и согласен с тем, что вы должны разоблачить только то, что вам действительно нужно. Исключением будет библиотека или инструментарий, где вы ожидаете, что пользователи захотят расширить (в общем смысле) ваш код способами, которые вы никогда не предвидели. В этом случае защита выбранных методов может рассматриваться как обеспечивающая гибкость.
Я думаю, вы должны только разоблачить, что вам нужно, когда вам нужно. Это облегчает оценку воздействия изменений. т.е. если метод является закрытым, вы знаете, что воздействие будет минимальным, если вы его измените.
Если вы намереваетесь создать класс для наследования, вы должны его спроектировать таким образом, то есть сделать эти методы защищенными, чтобы другие разработчики могли изменять поведение класса в соответствии с вашими линиями. Простое создание всех защищенных методов – не очень хороший дизайн. Имейте в виду, что все защищенные методы становятся частью общедоступного API, поэтому, если вы измените ситуацию позже, вы нарушите код других людей.
В общем, если вы не разрабатываете для наследования, вы должны запретить это.
Лично я считаю нужным сделать так много, насколько возможно. Я просто смотрю на каждый метод и спрашиваю себя, хочу ли я, чтобы производный класс мог его назвать. Предоставление всех защищенных листьев открывает дверь для неправильного использования методов.
Я догадываюсь, что это сводится к вопросам: «Все ли запрещено, если только это не разрешено» или «Все разрешено, если специально не запрещено.
Еще один фактор заключается в том, что легко сделать частный метод защищенным в будущей версии. Практически невозможно приватизировать метод, когда он защищен, так как вы никогда не знаете, какой другой код вы признаете недействительным.
Ну, личное ключевое слово предназначалось с определенной целью. Если вы не хотите, чтобы переменные загромождали ваши унаследованные классы (или вы не хотите, чтобы люди играли с ними в унаследованных классах), то почему вы даже считаете их защищенными?
Не позволяйте людям прикасаться к вашим частям 🙂
Обычно я избегаю private
. Мое рассуждение гласит, что если у вас есть отношение наследования между двумя классами, и есть частные члены, то это очень убедительно свидетельствует о том, что вы должны учитывать частные детали в отдельный объект.
Я бы назвал методы приватными. Это ясно указывает, что они не являются частью публичного API.
Не беспокойтесь о том, что может произойти в будущем.
Если реализованная вами функция относится к классу и не должна использоваться вне контекста этого класса, не допускайте ее наследования. Например, если бы у нас была иерархия животных, и у одного из животных было что-то невероятно уникальное для них, скажем, «layEggsInSand ()», как черепаха. Это может быть совершенно уникальным для черепахи (черепаха, что бы ни было!) Поэтому не должно быть унаследовано каким-либо другим животным. В этом контексте мы бы сказали, что это личное. С другой стороны, если функция «walk ()», то она не уникальна, поэтому она должна быть наследуемой.
Поначалу кажется довольно нечетким, потому что в большинстве случаев вещи должны быть унаследованы, но есть более редкие случаи, когда они не должны наследоваться, поскольку они уникальны для этого типа.
Как сказано, если вы собираетесь расширить класс позже, вы всегда сможете его изменить.
Но если вы можете избежать использования наследования, вы должны. Лучше использовать другие шаблоны при проектировании, если это возможно.
В основном, что делать, это поддержка композиции над наследованием и программа для интерфейсов, а не реализации.
Если вы позволяете классам иметь одну четко определенную цель, чем вы можете создавать объекты, а не позволять им наследовать друг друга. Если вы используете интерфейсы, а не наследование, вы, скорее всего, определите малые и эффективные интерфейсы. Затем вы увидите, что наследование уменьшится, и, следовательно, необходимость защиты уменьшится.
пример
interface sound { public function makeSound(); } class bark implements sound{ public function makeSound() { return "Bark!!!"; } } class mew implements sound{ public function makeSound() { return "Mewmew!!!"; } } class forLeggedAnimal { private $sound; public function forLeggedAnimal($sound){ $this->sound = $sound; } public function eat(){ echo $this->sound->makeSound(); } } $cat = new forLeggedAnimal(new mew()); $dog = new forLeggedAnimal(new bark());
Я знаю, что это далеко не прекрасный пример. Но это иллюстрирует технику, и вы можете использовать ее разными способами. Например, вы можете комбинировать это с различными шаблонами создания для создания кошек и собак, возможно, не так уж и важно знать, что кошка лает или кончает. Но в любом случае .. она отличается от необходимости делать базовый класс, а затем расширяться это с кошкой и собакой, и поэтому они должны сделать метод «звука» защищенным или переопределяющим метод общественного питания
/Питер
Обычно я использую private в очень специфическом случае, когда метод / переменная является очень внутренним и не должен быть прочитан или написан каким-либо другим подклассом (так что почти никогда не бывает). Единственный случай, когда я использую приватную переменную, – это пример:
final public function init():void { if(!_initialized) { _init(); _initialized = true; } } protected function _init():void { // specific code. }
В большинстве других случаев методы и переменная должны быть полезны для наследования, по крайней мере, как функция чтения. Поскольку большую часть времени, когда я использую код, сделанный кем-то другим, и когда этот код использует личные вещи, он всегда и с большим количеством проблем:
если он защищен (или если я его изменяю как защищенный), то я не могу переработать код (также добавив поведения между буксировкой других команд, потому что часть этого кода использует частные методы или переменные …
= на концах вы почти меняете весь аксессор на защищенный, чтобы получить возможность расширения класса!
Таким образом, если вы считаете, что этот класс может быть расширен, предпочтительнее защищать все, кроме особого случая (если вы считаете, что конкретный метод следует использовать, но не изменять, используйте final protected).
Если вы считаете, что этот класс не должен быть расширен в любом случае: используйте private.