Что такое шаблон заводского дизайна в PHP?
Это смущает меня, в самых простых терминах, что он делает? Представьте, что вы объясняете своей матери или кому-то почти пожалуйста.
9 ответов:
фабрика создает объект. Так что, если вы хотите построить
class A{ public $classb; public $classc; public function __construct($classb, $classc) { $this->classb = $classb; $this->classc = $classc; } }
вы не хотели бы полагаться на то, чтобы делать следующий код каждый раз, когда вы создаете объект
$obj = new ClassA(new ClassB, new Class C);
вот где завод пришел бы. Мы определяем фабрику, чтобы заботиться о том, что для нас:
class Factory{ public function build() { $classc = $this->buildC(); $classb = $this->buildB(); return $this->buildA($classb, $classc); } public function buildA($classb, $classc) { return new ClassA($classb, $classc); } public function buildB() { return new ClassB; } public function buildC() { return new ClassC; } }
теперь все, что нам нужно сделать, это
$factory = new Factory; $obj = $factory->build();
реальное преимущество, когда вы хотите изменить класс. Допустим, мы хотели пройти в другой ClassC:
class Factory_New extends Factory{ public function buildC(){ return new ClassD; } }
или новый ClassB:
class Factory_New2 extends Factory{ public function buildB(){ return new ClassE; } }
теперь мы можем использовать наследование, чтобы легко изменить способ создания класса, чтобы поместить в другой набор классов.
хорошим примером может быть этот класс пользователей:
class User{ public $data; public function __construct($data) { $this->data = $data; } }
в этом классе
$data
- это класс, мы используем для хранения наших данных. Теперь для этого класса, скажем, мы используем сеанс для хранения наших данных. Фабрика будет выглядеть так:class Factory{ public function build() { $data = $this->buildData(); return $this->buildUser($data); } public function buildData() { return SessionObject(); } public function buildUser($data) { return User($data); } }
теперь вместо того, чтобы сказать, что мы хотите сохранить все наши данные в базе данных, это действительно просто, чтобы изменить его:
class Factory_New extends Factory{ public function buildData() { return DatabaseObject(); } }
фабрики-это шаблон проектирования, который мы используем для управления тем, как мы собираем объекты вместе, и использование правильных заводских шаблонов позволяет нам создавать индивидуальные объекты, которые нам нужны.
как реальная фабрика жизни, она создает что-то и возвращает его.
представьте себе, что-то вроде этого
$joe = new Joe(); $joe->say('hello');
или заводским методом
Joe::Factory()->say('hello');
реализация метода factory создаст новый экземпляр и вернет его.
шаблон проектирования фабрики очень хорош, когда вы имеете дело с несколькими ресурсами и хотите реализовать абстракцию высокого уровня.
давайте разберем это в другой раздел.
Предположим, вам нужно реализовать абстракцию, и пользователю вашего класса не нужно заботиться о том, что вы реализовали в определении класса.
ему просто нужно беспокоиться об использовании методов вашего класса.
например, у вас есть две базы данных для вашего проекта
class MySQLConn { public function __construct() { echo "MySQL Database Connection" . PHP_EOL; } public function select() { echo "Your mysql select query execute here" . PHP_EOL; } } class OracleConn { public function __construct() { echo "Oracle Database Connection" . PHP_EOL; } public function select() { echo "Your oracle select query execute here" . PHP_EOL; } }
ваш класс завода будет заботиться о создании объекта для подключения к базе данных.
class DBFactory { public static function getConn($dbtype) { switch($dbtype) { case "MySQL": $dbobj = new MySQLConn(); break; case "Oracle": $dbobj = new OracleConn(); break; default: $dbobj = new MySQLConn(); break; } return $dbobj; } }
пользователю просто нужно передать имя типа базы данных
$dbconn1 = DBFactory::getConn("MySQL"); $dbconn1->select();
выход:
MySQL Database Connection Your mysql select query execute here
в будущем у вас может быть другая база данных, тогда вам не нужно менять весь код, нужно только передать новый тип базы данных, а другой код будет работать без каких-либо изменений изменения.
$dbconn2 = DBFactory::getConn("Oracle"); $dbconn2->select();
выход:
Oracle Database Connection Your oracle select query execute here
надеюсь, что это поможет.
В общем случае " фабрика "производит что-то: в случае объектно-ориентированного программирования" фабричный шаблон проектирования " производит объекты.
это не имеет значения, если это в PHP, C# или любой другой объектно-ориентированный язык.
заводская модель дизайна (заводская модель) предназначена для свободного соединения. Как и значение фабрики, данные на фабрику (производят данные) для конечного пользователя. Таким образом, завод разрывает плотную связь между источником данных и процессом обработки данных.
фабрика просто генерирует объект или объекты.
У вас может быть фабрика, которая строит соединение MySQL.
этот ответ относится к другому сообщению, в котором Даниэль Уайт сказал использовать factory для создания соединения MySQL с использованием заводского шаблона.
для подключения MySQL я бы предпочел использовать одноэлементный шаблон, поскольку вы хотите использовать одно и то же соединение для доступа к базе данных не создавать еще один.
классический подход к созданию экземпляра объекта:
$Object=new ClassName();
PHP имеет возможность динамически создавать объект из имени переменной, используя следующий синтаксис:
$Object=new $classname;
где переменная $classname содержит имя класса, который нужно создать.
таким образом, классический факторинг объектов будет выглядеть так:
function getInstance($classname) { if($classname==='Customer') { $Object=new Customer(); } elseif($classname==='Product') { $Object=new Product(); } return $Object; }
и если вы вызываете функцию getInstance ('Product'), эта фабрика создаст и вернет объект продукта. В противном случае, если вы вызов функции getInstance ('Customer') эта фабрика создаст и вернет объект типа Customer (созданный из класса Customer ()).
в этом больше нет необходимости, можно отправить "продукт" или "клиент" (точные имена существующих классов) в качестве значения переменной для динамического экземпляра:
$classname='Product'; $Object1=new $classname; //this will instantiate new Product() $classname='Customer'; $Object2=new $classname; //this will instantiate new Customer()
для записи, в простых словах, фабрика, как @Pindatjuh сказал, возвращает объект.
Так в чем же разница с конструктором? (что делает то же самое)
- конструктор использует свой собственный экземпляр.
- что-то я хочу, чтобы что-то более продвинутое, и я не хочу раздувать объект (или добавлять зависимости).
конструктор вызывается при создании экземпляра. Иногда ты этого не хочешь.
для например, предположим, что каждый раз, когда я создаю объект учетной записи класса, я читаю из базы данных файл и использую его в качестве шаблона.
С помощью конструктора:
class Account { var $user; var $pwd; var ... public __construct() { // here i read from the file // and many other stuff } }
С помощью фабрики:
class Account { var $user; var $pwd; var ... } class AccountFactory { public static Create() { $obj=new Account(); // here we read the file and more stuff. return $obj; }