Теперь мы можем использовать наследование, чтобы легко изменить способ создания класса, чтобы добавить другой набор классов.
Хорошим примером может быть этот пользовательский класс:
classUser{
public $data;
publicfunction__construct($data)
{
$this->data = $data;
}
}
В этом классе $dataнаходится класс, который мы используем для хранения наших данных. Теперь для этого класса, допустим, мы используем сеанс для хранения наших данных. Завод будет выглядеть так:
Фабрики - это шаблон проектирования, который мы используем для управления тем, как мы собираем объекты, а использование правильных фабричных шаблонов позволяет нам создавать индивидуальные объекты, которые нам нужны.
Это было много печатать. Теперь мне придется в какой-то момент разместить это в своей вики.
Тайлер Картер
1
Приятно и полезно. Снимаю шляпу перед тобой, приятель.
stefgosselin
1
В чем разница / польза от вашего кода $obj = $factory->build();более $obj = new whateverClass();? Кроме того, в другом классе (скажем, classZ), который зависит от данных classA, где в classZ вы бы использовали фабричный метод? По сути, вы по-прежнему создаете экземпляр класса (classZ) внутри класса (classA), что означает отсутствие тестирования. например, кажется, что factory - это просто загрузка кода, которую нужно выполнять с newпомощью метода, а не просто использовать new.
Джеймс
19
Как настоящая фабрика, она что-то создает и возвращает.
Представьте себе что-то вроде этого
$joe = new Joe();
$joe->say('hello');
или заводским методом
Joe::Factory()->say('hello');
Реализация фабричного метода создаст новый экземпляр и вернет его.
Хороший пример меня поражает, насколько разнообразны реализации этого шаблона. Я предполагаю, что при статическом вызове можно получить ссылку на экземпляр для повторного использования того же экземпляра позже? т.е. $ joe = Joe :: Factory () -> say ('привет');
stefgosselin
конечно, как и в версии 5.6, можно также сделать (new Joe ()) -> say ('hello');
Панчо
12
Шаблон проектирования Factory очень хорош, когда вы имеете дело с несколькими ресурсами и хотите реализовать абстракцию высокого уровня.
Давайте разберем это на разные разделы.
Предположим, вам нужно реализовать абстракцию, и пользователю вашего класса не нужно заботиться о том, что вы реализовали в определении класса.
Ему / ей просто нужно беспокоиться об использовании ваших методов класса.
например, у вас есть две базы данных для вашего проекта
MySQL Database Connection
Your mysql select query execute here
В будущем у вас может быть другая база данных, тогда вам не нужно менять весь код, нужно только передать новый тип базы данных, и другой код будет работать без каких-либо изменений.
Заводской шаблон проектирования (Factory Pattern) предназначен для слабой связи. Как и значение фабрики, данные для фабрики (производят данные) для конечного пользователя. Таким образом, фабрика нарушает тесную связь между источником данных и процессом обработки данных.
Этот ответ относится к другому сообщению, в котором Дэниел Уайт сказал использовать factory для создания соединения MySQL с использованием шаблона factory.
Для подключения к MySQL я бы предпочел использовать одноэлементный шаблон, поскольку вы хотите использовать одно и то же соединение для доступа к базе данных, а не создавать другое.
и если вы вызовете функцию getInstance ('Product'), эта фабрика создаст и вернет объект Product. В противном случае, если вы вызовете функцию getInstance ('Customer'), эта фабрика создаст и вернет объект типа Customer (созданный из класса Customer ()).
В этом больше нет необходимости, можно отправить 'Product' или 'Customer' (точные имена существующих классов) в качестве значения переменной для динамического создания экземпляра:
$classname='Product';
$Object1=new $classname; //this will instantiate new Product()
$classname='Customer';
$Object2=new $classname; //this will instantiate new Customer()
Для записи, простыми словами, такая фабрика, как сказал @Pindatjuh, возвращает объект.
Итак, в чем разница с конструктором? (что делает то же самое)
конструктор использует свой собственный экземпляр.
Что-то, чего я хочу, чтобы что-то более продвинутое, и я не хочу раздувать объект (или добавлять зависимости).
Конструктор вызывается при создании каждого экземпляра. Иногда вы этого не хотите.
Например, предположим, что каждый раз, когда я создаю объект класса Account, я читаю из базы данных файл и использую его в качестве шаблона.
Используя конструктор:
classAccount{
var $user;
var $pwd;
var ...
public __construct() {
// here i read from the file// and many other stuff
}
}
Использование фабрики:
classAccount{
var $user;
var $pwd;
var ...
}
classAccountFactory{
publicstatic Create() {
$obj=new Account();
// here we read the file and more stuff.return $obj;
}
Ответы:
Фабрика создает объект. Итак, если вы хотели построить
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(); } }
Фабрики - это шаблон проектирования, который мы используем для управления тем, как мы собираем объекты, а использование правильных фабричных шаблонов позволяет нам создавать индивидуальные объекты, которые нам нужны.
источник
$obj = $factory->build();
более$obj = new whateverClass();
? Кроме того, в другом классе (скажем, classZ), который зависит от данных classA, где в classZ вы бы использовали фабричный метод? По сути, вы по-прежнему создаете экземпляр класса (classZ) внутри класса (classA), что означает отсутствие тестирования. например, кажется, что factory - это просто загрузка кода, которую нужно выполнять сnew
помощью метода, а не просто использоватьnew
.Как настоящая фабрика, она что-то создает и возвращает.
Представьте себе что-то вроде этого
$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; } }
Ваш класс Factory позаботится о создании объекта для подключения к базе данных.
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();
Выход:
В будущем у вас может быть другая база данных, тогда вам не нужно менять весь код, нужно только передать новый тип базы данных, и другой код будет работать без каких-либо изменений.
$dbconn2 = DBFactory::getConn("Oracle"); $dbconn2->select();
Выход:
Надеюсь, это поможет.
источник
В общем, «фабрика» что-то производит: в случае объектно-ориентированного программирования «фабричный шаблон проектирования» производит объекты.
Неважно, на PHP, C # или на любом другом объектно-ориентированном языке.
источник
Заводской шаблон проектирования (Factory Pattern) предназначен для слабой связи. Как и значение фабрики, данные для фабрики (производят данные) для конечного пользователя. Таким образом, фабрика нарушает тесную связь между источником данных и процессом обработки данных.
источник
Фабрика просто генерирует объект или объекты.
У вас может быть фабрика, которая строит соединение MySQL.
http://en.wikipedia.org/wiki/Factory_method_pattern
источник
Этот ответ относится к другому сообщению, в котором Дэниел Уайт сказал использовать factory для создания соединения MySQL с использованием шаблона factory.
Для подключения к 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'), эта фабрика создаст и вернет объект Product. В противном случае, если вы вызовете функцию getInstance ('Customer'), эта фабрика создаст и вернет объект типа Customer (созданный из класса Customer ()).
В этом больше нет необходимости, можно отправить 'Product' или 'Customer' (точные имена существующих классов) в качестве значения переменной для динамического создания экземпляра:
$classname='Product'; $Object1=new $classname; //this will instantiate new Product() $classname='Customer'; $Object2=new $classname; //this will instantiate new Customer()
источник
Для записи, простыми словами, такая фабрика, как сказал @Pindatjuh, возвращает объект.
Итак, в чем разница с конструктором? (что делает то же самое)
Конструктор вызывается при создании каждого экземпляра. Иногда вы этого не хотите.
Например, предположим, что каждый раз, когда я создаю объект класса Account, я читаю из базы данных файл и использую его в качестве шаблона.
Используя конструктор:
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; }
источник