Подтвердить что ты не робот

Создать экземпляр класса из статического метода

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

class Foo{

 public $val;

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

}

Который поэтому позволяет мне это делать.

$obj = Foo::bar("some variable");

Это здорово.

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

Спасибо.

4b9b3361

Ответ 1

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

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

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

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

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

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

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

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

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

Я надеюсь, что это поможет...

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

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

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

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

Ответ 2

Это выглядит как простой шаблон метода factory.

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

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

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

ссылки:

Ответ 3

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

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

$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 в функции может исчезнуть, поэтому вы можете даже добавить параметр значения в свой частный конструктор, но делать другие вещи (которые вы, по-видимому, хотите сделать, например, проверить какой-то одноэлементный шаблон) в вашем Функция "бар"