статические функции PHP против функций экземпляра, основы - PullRequest
3 голосов
/ 17 сентября 2011

Я пытаюсь узнать, когда следует использовать статические функции, и мне было трудно найти ответ на мои вопросы. Я создаю класс User, который связан с классом Group. Если у меня есть идентификатор пользователя, и я хочу получить от него объект пользователя, лучше сделать что-то вроде

$existingUser = User::get($userId); 

где класс определяется следующим образом

class User()
{ 
    public static function get($id){
        $user = new User();
        return $user->findById($id);
    }
    public function findById($id) {
        //find and populate user object
    }
}

или

$existingUser=new User();
$existingUser->findById($userId);

где класс определяется так

class User()
{ 
    public function findById($id) {
        //find and populate user object
    }
}

Что если я напишу функцию, которая возвращает массив объектов Group на основе идентификатора пользователя?

class User()
{ 
    //stuff
    $groupArray = Group::getAllByUserId($this->getId())
    //stuff
}

или

class User()
{ 
    //stuff
    $group = new Group();
    $groupArray = $group->findAllByUserId($this->getId());
    //stuff
}

Второй метод создает пустой групповой объект, который никогда не используется. Это имеет значение? Я неправильно понимаю концепцию статики? Я знаю, что это полезно для того, чтобы не создавать экземпляры класса, так что, если функция создает экземпляр в любом случае, это побеждает такую ​​цель? Если это так, что будет примером того, когда будет использоваться статическая функция?

Что-нибудь еще, что я должен рассмотреть в этом упрощенном примере?

Ответы [ 4 ]

0 голосов
/ 17 сентября 2011

Я пытаюсь узнать, когда следует использовать статические функции

О, это так просто: никогда .

Чтобы понять это, прочитайте:
http://www.objectmentor.com/resources/articles/ocp.pdf
http://misko.hevery.com/code-reviewers-guide/flaw-brittle-global-state-singletons/

0 голосов
/ 17 сентября 2011

Вам не нужна статическая функция в случае, который вы показываете выше.

Статические функции - это на самом деле просто глобальные функции с пространством имен.

Используйте их, когда необходимо контролировать глобальное состояние приложения или если несколько копий функции приводят к несостоятельным результатам.

Иногда обратные вызовы должны быть статическими, особенно если они передаютсяв виде строки.

0 голосов
/ 17 сентября 2011

Я считаю, что хорошее эмпирическое правило заключается в том, чтобы думать: «Если у меня нет [имя-класса], могу ли я ожидать вызова [имя-метода]?»

Если у меня нет пользователя, могу ли я ожидать вызова findByID? Возможно нет. Это одно из исключений, с которыми я сталкиваюсь; метод "load" или "save" иногда имеет смысл быть статичным.

Прекрасным примером того, когда следует использовать нестатические методы, является (большинство методов в) класс Database - у вас всегда должен быть объект базы данных, прежде чем пытаться выполнить запрос к нему.

Примером использования статического метода может быть «вспомогательный» класс, по сути, набор удобных функций. Скажем, у вас есть несколько методов, которые помогут вам выводить HTML, у вас могут быть HTML::image(), HTML::url() и HTML::script(). На них вам не нужен HTML-объект для создания изображения, URL и т. Д.

Что касается остановки нескольких копий создаваемых объектов (один аргумент для использования статических методов), вы должны использовать шаблон Singleton (Google it), чтобы гарантировать, что когда-либо существует только одна копия объекта.

0 голосов
/ 17 сентября 2011

Вам, вероятно, стоит проверить этот вопрос в Active Record против data mapper:

https://stackoverflow.com/questions/2169832/data-mapper-vs-active-record

Одним из выводов этого вопроса является то, что статические методы класса для загрузки / сохранения в действительности не являются основной функциональностью класса. Кроме того, хранение и загрузка - это некое абстрактное понятие, которое в большинстве случаев отделено от объектов вашего класса.

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

...