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

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: Изучаю паттер - Factory method. Правильно ли я понял этот шаблон?

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


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

> Без описания
Сайга-12
Отправлено: 26 Июля, 2015 - 17:54:46
Post Id



Гость


Покинул форум
Сообщений всего: 68
Дата рег-ции: Дек. 2013  


Помог: 0 раз(а)




Доброго времени суток.
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.  


Правильно ли я понимаю этот шаблон? Если нет, то в чём ошибка?
 
 Top
Мелкий Супермодератор
Отправлено: 26 Июля, 2015 - 20:21:35
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




Сайга-12 пишет:
При этом способ создания объекта у него может быть совершенно разный

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

Важно: фабрика на каждый вызов создаёт новый объект и все объекты, которые может породить конкретная фабрика, должны реализовывать один интерфейс.


-----
PostgreSQL DBA
 
 Top
Viper
Отправлено: 26 Июля, 2015 - 20:39:22
Post Id



Активный участник


Покинул форум
Сообщений всего: 4555
Дата рег-ции: Февр. 2007  
Откуда: Симферополь


Помог: 98 раз(а)




Сайга-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();

(Отредактировано автором: 26 Июля, 2015 - 20:40:48)



-----
Список фильмов с описанием, блекджеком и... для Joomla? -> https://киноархив[dot]com
Демо нового движка для сайта php.su -> php[dot]su, проект на гитхабе
 
 Top
MiksIr
Отправлено: 26 Июля, 2015 - 20:53:23
Post Id


Забанен


Покинул форум
Сообщений всего: 378
Дата рег-ции: Сент. 2014  


Помог: 10 раз(а)

[+]


Viper, только вот то, что вы написали - называется Синглтон, что есть совершенно иной патерн.
(Добавление)
Цитата:
Кстати, как называется такое явление, когда по значению переменной создают объект класса?

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

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

(Отредактировано автором: 26 Июля, 2015 - 20:57:16)



-----
self-banned
 
 Top
Viper
Отправлено: 26 Июля, 2015 - 21:01:35
Post Id



Активный участник


Покинул форум
Сообщений всего: 4555
Дата рег-ции: Февр. 2007  
Откуда: Симферополь


Помог: 98 раз(а)




MiksIr пишет:
только вот то, что вы написали - называется Синглтон, что есть совершенно иной патерн.
угумс.


-----
Список фильмов с описанием, блекджеком и... для Joomla? -> https://киноархив[dot]com
Демо нового движка для сайта php.su -> php[dot]su, проект на гитхабе
 
 Top
Сайга-12
Отправлено: 26 Июля, 2015 - 21:48:19
Post Id



Гость


Покинул форум
Сообщений всего: 68
Дата рег-ции: Дек. 2013  


Помог: 0 раз(а)




MiksIr пишет:
Viper, только вот то, что вы написали - называется Синглтон, что есть совершенно иной патерн.
(Добавление)
Цитата:
Кстати, как называется такое явление, когда по значению переменной создают объект класса?

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

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


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

Будет называться "Simple method"?
 
 Top
MiksIr
Отправлено: 26 Июля, 2015 - 21:59:05
Post Id


Забанен


Покинул форум
Сообщений всего: 378
Дата рег-ции: Сент. 2014  


Помог: 10 раз(а)

[+]


Нет. Найдите описание паттерна и не выдумывайте логики.


-----
self-banned
 
 Top
caballero
Отправлено: 26 Июля, 2015 - 22:09:07
Post Id


Активный участник


Покинул форум
Сообщений всего: 5998
Дата рег-ции: Сент. 2011  
Откуда: Харьков


Помог: 126 раз(а)




Цитата:
Factory method - я понял, как класс, метод у которого, создаёт объект определённого типа.

фабричные методы создают экземпляры класса, членами которого являются, а не шо попало.


-----
Бесплатная система складского учета с открытым кодом https://zippy[dot]com[dot]ua/zstore
 
 Top
Viper
Отправлено: 26 Июля, 2015 - 22:18:08
Post Id



Активный участник


Покинул форум
Сообщений всего: 4555
Дата рег-ции: Февр. 2007  
Откуда: Симферополь


Помог: 98 раз(а)




Короче в разных источниках по разному написано. Хрен знает кому верить... Пойду Попова почитаю...


-----
Список фильмов с описанием, блекджеком и... для Joomla? -> https://киноархив[dot]com
Демо нового движка для сайта php.su -> php[dot]su, проект на гитхабе
 
 Top
Panoptik
Отправлено: 26 Июля, 2015 - 22:29:25
Post Id



Постоянный участник


Покинул форум
Сообщений всего: 2493
Дата рег-ции: Нояб. 2011  
Откуда: Одесса, Украина


Помог: 131 раз(а)




caballero пишет:
фабричные методы создают экземпляры класса, членами которого являются, а не шо попало.

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

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

и исходя из такой логики
можно ли назвать методы различных моделей ORM а-ля Model::find, Model::findByPk, Model::findOne фабричными методами, хотя эти методы зачастую будут принимать дополнительные параметры чтобы создать объект именно с теми характеристиками, которые нужны?


-----
Just do it
 
 Top
MiksIr
Отправлено: 27 Июля, 2015 - 00:45:41
Post Id


Забанен


Покинул форум
Сообщений всего: 378
Дата рег-ции: Сент. 2014  


Помог: 10 раз(а)

[+]


caballero пишет:
фабричные методы создают экземпляры класса, членами которого являются, а не шо попало.

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

Начните с банды четырех https://ru[dot]wikipedia[dot]org/wiki/Design_Patterns


-----
self-banned
 
 Top
caballero
Отправлено: 27 Июля, 2015 - 13:36:14
Post Id


Активный участник


Покинул форум
Сообщений всего: 5998
Дата рег-ции: Сент. 2011  
Откуда: Харьков


Помог: 126 раз(а)




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

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

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

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

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

начните с ПРАКТИЧЕСКОГО програмирования и не вумных книжек с теорией


-----
Бесплатная система складского учета с открытым кодом https://zippy[dot]com[dot]ua/zstore
 
 Top
MiksIr
Отправлено: 27 Июля, 2015 - 14:15:23
Post Id


Забанен


Покинул форум
Сообщений всего: 378
Дата рег-ции: Сент. 2014  


Помог: 10 раз(а)

[+]


Цитата:
начните с ПРАКТИЧЕСКОГО програмирования и не вумных книжек с теорией

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


-----
self-banned
 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« Объектно-ориентированное программирование »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB