унаследованный метод фабрики должен возвращать экземпляры собственного класса, а не наследуемого класса - PullRequest
0 голосов
/ 26 августа 2010

У меня есть класс со сложным статическим фабричным методом, назовем его ClassA.Я расширил ClassA до ClassB, и я хочу, чтобы фабричный метод ClassB делал все, что делает фабричный метод ClassA, за исключением возврата ClassB.

class ClassA{
   static public function Factory($construct_args, $contents){
      $new = new ClassA($construct_args);
      //Does lots of stuff with $contents
   }
}

class ClassB extends ClassA{
   //specialty methods and properties
}

echo get_class(ClassB::Factory($construct_args, $contents);

Это должно повториться ClassB

Есть лиКак я могу использовать фабричный метод ClassA без копирования его в ClassB?Я использую PHP5, но не 5.3.0.

Ответы [ 3 ]

2 голосов
/ 26 августа 2010

Чтобы сделать именно то, что вам нужно, вам нужно Позднее статическое связывание , поэтому вам нужен PHP 5.3.Это не может быть сделано, как вы хотите в PHP 5.2.Люди пытались.

Обходные пути, которые я видел / использовал для 5.2:

  1. Как вы упоминали (и не хотите делать), скопируйте ваш фабричный метод вкаждый класс

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

  3. Требуются ваши фабрикиреализовать интерфейс или сделать так, чтобы они наследовали от абстрактного класса (или просто знают соглашение), который требует определения статического метода «getClassName», который будет использоваться на фабрике.Это похоже на номер один, но некоторые люди предпочитают его, поскольку это позволяет их фабричному методу оставаться в «нижнем» классе.

0 голосов
/ 26 августа 2010

В PHP 5.3 это просто вопрос выполнения ( см. Поздние статические привязки ):

static public function Factory($construct_args, $contents){
   $new = new static($construct_args);
   //Does lots of stuff with $contents
   return $new;
}

В PHP 5.2 вы должны быть более креативными. Что-то вроде:

class ClassA {
   static function Factory($construct_args, $contents) {
       return self::privFactory($construct_args, $contents, "ClassA");
   }
   static protected function privFactory($construct_args, $contents, $type){
      $new = new $type($construct_args);
      //Does lots of stuff with $contents
      return $new;
   }
}

class ClassB extends ClassA{
   static function Factory($construct_args, $contents) {
       return self::privFactory($construct_args, $contents, "ClassB");
   }
}
0 голосов
/ 26 августа 2010

Полагаю, это случай Позднее статическое связывание .Если вы не используете 5.3, вы должны скопировать его.

Однако вы также можете удалить фабричный метод из ClassA и превратить его в специальный класс Factory или Builder, который знает, как создавать ClassA и любые специальные классывместо этого.

...