Це мене бентежить, найпростішими словами, що це робить? Прикиньтесь, що пояснюєте матері чи комусь майже будь-ласка.
Це мене бентежить, найпростішими словами, що це робить? Прикиньтесь, що пояснюєте матері чи комусь майже будь-ласка.
Відповіді:
Фабрика створює об'єкт. Отже, якщо ви хотіли будувати
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
є клас, який ми використовуємо для зберігання наших даних. Тепер для цього класу, скажімо, ми використовуємо Session для зберігання наших даних. Завод буде виглядати так:
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, де в класіZ ви б використовували заводський метод? По суті, ви все ще створюєте екземпляр класу (classZ) у класі (classA), що означає відсутність тестування. наприклад, фабрика просто здається навантаженням коду, який потрібно зробити new
за допомогою методу, а не просто використовувати new
.
Як фабрика реального життя, вона щось створює і повертає.
Уявіть щось подібне
$joe = new Joe();
$joe->say('hello');
або фабричним способом
Joe::Factory()->say('hello');
Реалізація фабричного методу створить новий екземпляр і поверне його.
Заводський шаблон дизайну дуже хороший, коли ви маєте справу з кількома ресурсами і хочете застосувати абстракцію високого рівня.
Давайте розберемо це на інший розділ.
Припустимо, вам доведеться застосувати абстракцію, і користувачеві вашого класу не потрібно дбати про те, що ви реалізували у визначенні класу.
Йому / їй просто потрібно турбуватися про використання методів вашого класу.
наприклад, у вас є дві бази даних для вашого проекту
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
Сподіваюся, це допоможе.
Завод просто генерує об’єкт або об’єкти.
Можливо, у вас є фабрика, яка створює з’єднання MySQL.
Ця відповідь стосується іншого допису, в якому Даніель Уайт сказав використовувати фабрику для створення з'єднання 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'), ця фабрика створить і поверне об'єкт Product. В іншому випадку, якщо ви викликаєте функцію getInstance ('Клієнт'), ця фабрика створить і поверне об'єкт типу Клієнт (створений з класу Клієнт ()).
Більше це не потрібно, можна надіслати '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;
}