Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Форумы портала PHP.SU :: Версия для печати :: Изучаю паттер - Factory method. Правильно ли я понял этот шаблон?
Форумы портала PHP.SU » » Объектно-ориентированное программирование » Изучаю паттер - Factory method. Правильно ли я понял этот шаблон?

Страниц (1): [1]
 

1. Сайга-12 - 26 Июля, 2015 - 17:54:46 - перейти к сообщению
Доброго времени суток.
Factory method - я понял, как класс, метод у которого, создаёт объект определённого типа. При этом способ создания объекта у него может быть совершенно разный, например:
Через ифы:
PHP:
скопировать код в буфер обмена
  1.  
  2.         if (/* условие */)
  3.             return new class1();
  4.         else
  5.             return new class2();
  6.  

Через свитч кейсы:
PHP:
скопировать код в буфер обмена
  1.  
  2.         switch(/* переменная */)
  3.         {
  4.             case "class1": return new class1;
  5.             case "class2": return new class2;
  6.         }
  7.  

Или по значению переменной:
PHP:
скопировать код в буфер обмена
  1.  
  2.         $className = "class1";
  3.         return new $className();
  4.  


То есть природа создания объекта (каким способом программист создаёт объект) не столь важна, как сам факт создания объекта.

Кстати, как называется такое явление, когда по значению переменной создают объект класса?


Вот весь демонстрационный код.

PHP:
скопировать код в буфер обмена
  1.  
  2. <?PHP
  3. abstract class Greeting
  4. {
  5.     /**
  6.      * @var User
  7.      */
  8.     protected $user;
  9.     abstract public function make ();
  10.     public function setUser(User $user)
  11.     {
  12.         $this->user = $user;
  13.     }
  14.  
  15.  
  16. }
  17.  
  18. class GreetingAdmin extends Greeting
  19. {
  20.     public function make()
  21.     {
  22.         return $this->user->getLogin() . ", Вы - администратор.";
  23.     }
  24. }
  25.  
  26. class GreetingUser extends Greeting
  27. {
  28.     public function make()
  29.     {
  30.         return $this->user->getLogin() . ", Вы - обычный пользователь.";
  31.     }
  32. }
  33.  
  34. class User
  35. {
  36.     private $login;
  37.     private $password;
  38.     private $group;
  39.  
  40.     public function getGroup()
  41.     {
  42.         return $this->group;
  43.     }
  44.  
  45.  
  46.     /**
  47.      * @param $group
  48.      * @return $this
  49.      */
  50.     public function setGroup($group)
  51.     {
  52.         $this->group = $group;
  53.         return $this;
  54.     }
  55.  
  56.     /**
  57.      * @return string
  58.      */
  59.     public function getLogin()
  60.     {
  61.         return $this->login;
  62.     }
  63.  
  64.  
  65.     /**
  66.      * @param $login
  67.      * @return $this
  68.      */
  69.     public function setLogin($login)
  70.     {
  71.         $this->login = $login;
  72.         return $this;
  73.     }
  74.  
  75.     /**
  76.      * @return string
  77.      */
  78.     public function getPassword()
  79.     {
  80.         return $this->password;
  81.     }
  82.  
  83.  
  84.     /**
  85.      * @param $password
  86.      * @return $this
  87.      */
  88.     public function setPassword($password)
  89.     {
  90.         $this->password = $password;
  91.         return $this;
  92.     }
  93. }
  94.  
  95. class GreetingFactory
  96. {
  97.     private $user;
  98.     private $arrayGroup = ["User", "Admin"];
  99.     public function __construct(User $user)
  100.     {
  101.         $this->user = $user;
  102.     }
  103.  
  104.     /**
  105.      * @return Greeting
  106.      */
  107.     public function getObjectGreeting () // Это фабричный метод на мой взгляд.
  108.     {
  109.         $greeting = $this->createObject();
  110.         $greeting->setUser($this->user);
  111.  
  112.         return $greeting;
  113.     }
  114.     /**
  115.      * @return Greeting
  116.      */
  117.     private function createObject()
  118.     {
  119.         $className = "Greeting" . $this->arrayGroup[$this->user->getGroup()];
  120.         return new $className();
  121.     }
  122. }
  123.  
  124. $user = new User();
  125. $user
  126.     ->setGroup(1)
  127.     ->setLogin("Вася")
  128.     ->getPassword("qwerty")
  129. ;
  130.  
  131. $GreetingFactory = new GreetingFactory($user);
  132. $Greeting = $GreetingFactory->getObjectGreeting();
  133. echo $Greeting->make();
  134. ?>
  135.  


Правильно ли я понимаю этот шаблон? Если нет, то в чём ошибка?
2. Мелкий - 26 Июля, 2015 - 20:21:35 - перейти к сообщению
Сайга-12 пишет:
При этом способ создания объекта у него может быть совершенно разный

Да, вплоть до возвращает всегда объект одного и того же класса.

Важно: фабрика на каждый вызов создаёт новый объект и все объекты, которые может породить конкретная фабрика, должны реализовывать один интерфейс.
3. Viper - 26 Июля, 2015 - 20:39:22 - перейти к сообщению
Сайга-12 пишет:
Кстати, как называется такое явление, когда по значению переменной создают объект класса?
динамическое создание объекта.
Сайга-12 пишет:
То есть природа создания объекта (каким способом программист создаёт объект) не столь важна, как сам факт создания объекта.
да.

Лучше вместо конструктора, использовать статику. Так методы вызываются без инициализации класса.

PHP:
скопировать код в буфер обмена
  1. abstract class Factory {
  2.         public static $someVar;
  3.  
  4.         public static function getSomething()
  5.         {
  6.                 if (!self::$someVar)
  7.                 {
  8.                         self::$someVar = self::createSomething();
  9.                 }
  10.  
  11.                 return self::$someVar;
  12.         }
  13.  
  14.         protected static function createSomething()
  15.         {
  16.                 $var = SomeClass::getInstance();
  17.  
  18.                 return $var;
  19.         }
  20. }
  21.  
  22. class SomeClass {
  23.         public function __construct() {
  24.                 ...
  25.         }
  26.  
  27.         public static function getInstance() {
  28.                 ...
  29.                 return self::$vars;
  30.         }
  31.  
  32.         public function doSomething() {
  33.                 ...
  34.                 return $something;
  35.         }
  36. }
  37.  
  38. $factory = Factory::getSomething()->doSomething();
4. MiksIr - 26 Июля, 2015 - 20:53:23 - перейти к сообщению
Viper, только вот то, что вы написали - называется Синглтон, что есть совершенно иной патерн.
(Добавление)
Цитата:
Кстати, как называется такое явление, когда по значению переменной создают объект класса?

В разных местах встречал это под названием Simple factory.

Ибо классический паттер абтрактной фабрики не подразумевает в коде фабрики какого-то ветвления.
Абстрактная фабрикая сделана для того, что бы в процессе рефакторинга кода легко поменять объект А на объект Б, не меняя всякие new во всех местах кода. Просто меняется в одном классе-фабрике.
5. Viper - 26 Июля, 2015 - 21:01:35 - перейти к сообщению
MiksIr пишет:
только вот то, что вы написали - называется Синглтон, что есть совершенно иной патерн.
угумс.
6. Сайга-12 - 26 Июля, 2015 - 21:48:19 - перейти к сообщению
MiksIr пишет:
Viper, только вот то, что вы написали - называется Синглтон, что есть совершенно иной патерн.
(Добавление)
Цитата:
Кстати, как называется такое явление, когда по значению переменной создают объект класса?

В разных местах встречал это под названием Simple factory.

Ибо классический паттер абтрактной фабрики не подразумевает в коде фабрики какого-то ветвления.
Абстрактная фабрикая сделана для того, что бы в процессе рефакторинга кода легко поменять объект А на объект Б, не меняя всякие new во всех местах кода. Просто меняется в одном классе-фабрике.


Значит по той же логике, конструкция вида:
PHP:
скопировать код в буфер обмена
  1.  
  2. $object->$method(); //Где $method - это строка
  3.  

Будет называться "Simple method"?
7. MiksIr - 26 Июля, 2015 - 21:59:05 - перейти к сообщению
Нет. Найдите описание паттерна и не выдумывайте логики.
8. caballero - 26 Июля, 2015 - 22:09:07 - перейти к сообщению
Цитата:
Factory method - я понял, как класс, метод у которого, создаёт объект определённого типа.

фабричные методы создают экземпляры класса, членами которого являются, а не шо попало.
9. Viper - 26 Июля, 2015 - 22:18:08 - перейти к сообщению
Короче в разных источниках по разному написано. Хрен знает кому верить... Пойду Попова почитаю...
10. Panoptik - 26 Июля, 2015 - 22:29:25 - перейти к сообщению
caballero пишет:
фабричные методы создают экземпляры класса, членами которого являются, а не шо попало.

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

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

и исходя из такой логики
можно ли назвать методы различных моделей ORM а-ля Model::find, Model::findByPk, Model::findOne фабричными методами, хотя эти методы зачастую будут принимать дополнительные параметры чтобы создать объект именно с теми характеристиками, которые нужны?
11. MiksIr - 27 Июля, 2015 - 00:45:41 - перейти к сообщению
caballero пишет:
фабричные методы создают экземпляры класса, членами которого являются, а не шо попало.

Нет.
(Добавление)
Viper пишет:
ороче в разных источниках по разному написано. Хрен знает кому верить... Пойду Попова почитаю...

Начните с банды четырех https://ru[dot]wikipedia[dot]org/wiki/Design_Patterns
12. caballero - 27 Июля, 2015 - 13:36:14 - перейти к сообщению
Цитата:
ну и тут следовательно предположить, что весь цимес данного действа в возможности расширенной инициализации класса в один клик, то есть метод, хотя всю ту инициализацию можно перевести и в конструктор, с другой стороны конструктор должен быть более универсальным чем какой-то фабричный метод

ни фига не понял

Цитата:
иначе профита никакого в отличии от профита фабрики

профитов как минимум два:
- метод проще чем отдельный класс фабрики
- фабричный метод имеет доступ к приватным членам класса
(Добавление)
Цитата:
Нет.

Да
только индусы лепят отдельную фабрику с одним методом там где можно обойтись статическим методом класса создаваемого экземпляра
Цитата:
Начните с банды четырех

начните с ПРАКТИЧЕСКОГО програмирования и не вумных книжек с теорией
13. MiksIr - 27 Июля, 2015 - 14:15:23 - перейти к сообщению
Цитата:
начните с ПРАКТИЧЕСКОГО програмирования и не вумных книжек с теорией

Зачем, таких уже слишком много на рынке ;) ПХП-говнокодер называется.
Да и не получится у меня уже, образование не даст ;)))

 

Powered by ExBB FM 1.0 RC1