Лучше всего использовать частные методы или защищенные методы? - PullRequest
33 голосов
/ 07 января 2009

Во многих моих проектах PHP я получаю классы с непубличными функциями, которые я не собираюсь расширять.

Лучше ли объявлять их защищенными или частными?

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

С другой стороны, использует ли приват как-то антисоциально, так как это мешает будущему теоретическому разработчику расширять мой код без изменений?

Ответы [ 10 ]

24 голосов
/ 07 января 2009

Мой инстинкт - держать их в секрете, пока они вам не понадобятся.

Утверждалось (к сожалению, я неуместно разместил ссылку), что создание приватных методов антисоциально, во многом аналогично тому, как делать их "окончательными", поскольку это довольно диктаторский вопрос о том, как люди могут использовать ваш код. *

Я не уверен, однако, и согласен, что вы должны выставлять только то, что вам действительно нужно. Исключением будет библиотека или инструментарий, в котором пользователи ожидают, что пользователи захотят расширить (в общем смысле) ваш код способами, которые вы никогда не предвидели. В этом случае создание хорошо выбранных защищенных методов можно рассматривать как обеспечение гибких точек.

11 голосов
/ 07 января 2009

Я думаю, что вы должны показывать только то, что вам нужно, когда вам нужно. Это облегчает оценку воздействия изменений. Т.е. если метод закрытый, вы знаете , если вы его измените, влияние будет минимальным.

6 голосов
/ 07 января 2009

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

Я полагаю, что все сводится к вопросам "Запрещено ли все, если это не разрешено конкретно" или "Разрешено ли все, если не оговорено особо".

Еще одним фактором является то, что в будущем выпуске легко сделать защищенный частный метод. Приватизировать метод, как только он станет защищенным, практически невозможно, так как вы никогда не знаете, какой другой код вы аннулируете.

5 голосов
/ 07 января 2009

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

В общем, если вы не разрабатываете для наследования, вы должны запретить его.

3 голосов
/ 10 января 2009

Я вообще избегаю private. Я рассуждаю так: если у вас есть отношение наследования между двумя классами и есть закрытые члены, это очень убедительный показатель того, что вы должны выделить частные части в отдельный объект.

3 голосов
/ 07 января 2009

Ну, частное ключевое слово было предназначено с целью. Если вы не хотите, чтобы переменные загромождали ваши унаследованные классы (или вы не хотите, чтобы люди играли с ними в унаследованных классах), то почему вы даже подумываете сделать их защищенными?

Не позволяйте людям касаться ваших личных частей:)

1 голос
/ 26 июля 2009

Как уже говорилось, если вы собираетесь расширить класс позже, вы всегда можете изменить его.

Но если вы можете избежать использования наследования, вам следует. При проектировании лучше использовать другие шаблоны, если это возможно.

По сути, нужно отдавать предпочтение композиции, а не наследованию и программированию для интерфейсов, а не для реализаций.

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

Пример

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());

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

/ Петр

1 голос
/ 07 января 2009

Если реализованная вами функция специфична для класса и не должна использоваться вне контекста этого класса, не позволяйте ей наследоваться. Например, если у нас была иерархия животных, и у одного из животных было что-то невероятно уникальное для них, скажем «layEggsInSand ()», как черепаха. Это может быть полностью уникальным для черепахи (черепаха, что угодно!), Поэтому не должно наследоваться никаким другим животным. В этом контексте мы бы сказали, что это личное. С другой стороны, если функция "walk ()", то она не уникальна, поэтому она должна быть наследуемой.

Поначалу это кажется довольно нечетким, потому что большую часть времени вещи должны наследоваться, но есть более редкие случаи, когда они не должны наследоваться, поскольку они уникальны для этого типа.

1 голос
/ 07 января 2009

Я бы объявил методы закрытыми. Это ясно указывает на то, что они не являются частью общедоступного API.

Не беспокойтесь о том, что может произойти в будущем.

0 голосов
/ 02 мая 2014

Я обычно использую private в каком-то очень специфическом случае, когда метод / переменная очень внутренний и не должен быть прочитан или записан каким-либо другим подклассом (так что в основном почти никогда). Единственный случай, когда я использую закрытую переменную для примера:

final public function init():void
{
    if(!_initialized)
    {
        _init();
        _initialized = true;
    }

}

protected function _init():void
{
    // specific code.
}

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

  • требуемое поведение еще не реализовано или не завершено
  • Я не могу использовать метод, потому что он приватный
  • Я не могу изменить этот метод, потому что он приватный
  • если он защищен (или если я изменяю его как защищенный), то я не могу переработать код (иначе говоря, добавить поведение между двумя инструкциями других, потому что часть этого кода использует закрытые методы или переменные ...

    = на концах вы почти меняете все средства доступа на защищенные, чтобы получить возможность расширения класса!

Таким образом, если вы думаете, что этот класс может быть расширен, предпочитайте защищенный для всего, кроме очень специфического случая (если вы думаете, что должен использоваться только определенный метод, но не изменяться, используйте final protected).

Если вы считаете, что этот класс ни в коем случае не следует расширять, используйте private.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...