• Когда использовать protected, private, public и static методы?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    Есть такая штука в ООП как инкапсуляция. С этого стоит начать и в принципе можно было бы закончить, если бы не static и не protected.

    public
    Публичные методы класса. Логично да? Какие методы у нас должны быть публичными - те которые составляют интерфейс класса. То есть для, например, класса кеширования у нас должен быть такой интерфейс:
    interface Cache {
        public function get($name);
        public function set($name, $value);
        public function has($name);
        public function remove($name);
        public function removeAll();
    }


    Давайте введем понятие "клиентский код". Это тот код который будет использовать ваш код, ваши объекты. Что он должен знать о реализации ваших классов? Да ничего он знать не должен. Он должен знать только как им пользоваться. Это как раз таки интерфейс и регламентирует. Мол "этот объект позволяет вам брать/сохранять/удалять данные в/из кэша. Клиентский код не знает где кэш находится, есть ли он вообще... да и ему и не нужно.

    private
    Внутренние методы классов. Те которые не входят в интерфейс но нужны, скажем, для уменьшения дублирования реализации.

    class FileCache implements Cache{
        public function has($name) {
              return is_file($this->getCacheFilePath($name));
        }
    
        public function get($name) {
             if (!$this->has($name)) {
                  return null;
             }
     
             return unserialize(file_get_contents($this->getCacheFilePath($name)));
        }
    
        private function getCacheFilePath($name) {
             return $this->cacheDir . '/' . $name;
        }
    }


    protected
    Иногда у вас появляется необходимость вынести общую реализацию внутренних методов в базовый какой-то абстрактный класс. Например у вас есть несколько реализаций кеша для одного и того же хранилища или что-либо такое. Тогда вы заводите абстрактный класс, выносите туда всю общую реализацию в protected методах ну и т.д. Придумывать пример лень... Придумайте сами. Суть в том что protected методы желательно использовать только в абстрактных классах (но не как абстрактные методы, хотя всякое может быть) или если вы планируете дать возможность расширять ваш класс (но если честно, это крайне редко бывает).

    static
    Статические методы, это всяческие методы хелперы. Например в языках типа Java есть такое понятие как именованные конструкторы. Мол когда для конструирования объектов нужно много данных переделать или что-то еще, для удобства заводят статический метод какой а в нем уже реализуют какую-то логику. Желательно вообще что бы статический метод не содержал много логики, но... всякое бывает. Вообще тут стоит еще поподробнее почитать о том как себя ведут статические методы и свойства, в чем их особенность и т.д. Попробуйте тот же сингелтон сделать к примеру.

    class Template($content) {
        public static fromFile($path) {
             return new static(file_get_contents($path));
        }
    }


    Вот... Возможно человеки вроде FanatPHP разгромят мой ответ, или дополнят его...

    Так же если вам хочется научиться правильно составлять интерфейсы классов, следует почитать про low coupling и high cohesion. Эти два принципа должны заставить вас соблюдать баланс и держать в интерфейсе класса только то, что там должно быть. Так же к вопросу о наследовании можно подключить принцип подстановки Барбары Лисков. Даже на той же википедии почитайте. А там если станет интересно в принципе можно поискать интересные материалы по GRASP и SOLID.
    Ответ написан
    4 комментария