Создать экземпляр класса из статического метода - PullRequest
38 голосов
/ 11 января 2011

Как видно из заголовка, я хочу создать экземпляр класса из статического метода того же класса.До сих пор я выяснил, что я могу сделать что-то вроде этого:

class Foo{

 public $val;

 public static function bar($val){
  $inst = new Foo;
  $inst->val = $val;
  return $inst;
 }

}

, что позволяет мне делать это.1008 * Так что теперь вопросы.Есть ли более простой способ сделать это, о котором я не знаю, или какие-либо пути достижения того же результата?Есть ли какие-либо преимущества или недостатки создания экземпляра таким способом?

Спасибо.

Ответы [ 3 ]

84 голосов
/ 11 января 2011

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

  1. Не указывайте имя класса жестко.Если вы используете 5.3+, используйте ключевое слово static.Таким образом, если вы расширяете класс, новая функция также может создавать его экземпляр:

    public static function bar($var) {
        $obj = new static();
        $obj->var = $var;
        return $obj;
    }
    

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

  2. Выясните, следует ли передавать $var через конструктор, а не устанавливать после построения.Если объект зависит от него, вы должны его потребовать.

    public function __construct($var) {
        $this->var = $var;
    }
    

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

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

    protected function __construct() {}
    private function __construct() {}
    

Надеюсь, это поможет ...

Редактировать: На основеВаш комментарий выше звучит так, будто вы пытаетесь реализовать Singleton Design Pattern .Существует масса информации о том, почему это не лучшая идея и плохие вещи, которые она может сделать.У этого есть также использование.

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

  • Вы можете использовать Factory Method если вы пытаетесь создать разные объекты, используя одни и те же шаги.
  • Если все объекты начинаются одинаково, а затем настраиваются, вы можете использовать Prototype Pattern .
  • Вы можете использовать Object Pool , если создание объекта особенно дорого.

Но нужно учитывать одну вещь: в PHP объекты довольно легкие.Не пытайтесь избегать создания нового объекта только для этих накладных расходов.Избегайте выполнения тяжелых задач, таких как запросы к базе данных или доступ к файловой системе несколько раз.Но не беспокойтесь о вызове new Foo(), если конструктор foo не слишком тяжелый ...

3 голосов
/ 11 января 2011

Это похоже на простой шаблон фабричного метода.

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

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

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

ссылки:

  1. Шаблоны Php
  2. Шаблон фабричного метода в Википедии
0 голосов
/ 11 января 2011

Если вы просто создаете объект, это не очень полезно. Вы могли бы просто вызвать конструктор. Но если вы делаете что-то более сложное (например, вы начинаете с какого-то шаблона синглтона, но не включили все детали в этом примере), то:

Это звучит примерно так. Если вы хотите предотвратить создание объектов по умолчанию, как показано ниже:

$obj = new Foo("Some Variable");

Вы можете добавить приватный конструктор:

class Foo{

 public $val;

 private __construct(){}

 public static function bar($val){
  $inst = new Foo;
  $inst->val = $val;
  return $inst;
 }
}

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

...