Questo mi confonde, nei termini più semplici cosa fa? Fai finta di spiegare a tua madre oa qualcuno quasi per favore.
Questo mi confonde, nei termini più semplici cosa fa? Fai finta di spiegare a tua madre oa qualcuno quasi per favore.
Risposte:
Una fabbrica crea un oggetto. Quindi, se volessi costruire
class A{
public $classb;
public $classc;
public function __construct($classb, $classc)
{
$this->classb = $classb;
$this->classc = $classc;
}
}
Non vorrai fare affidamento sul dover eseguire il codice seguente ogni volta che crei l'oggetto
$obj = new ClassA(new ClassB, new Class C);
È qui che entra in gioco la fabbrica. Definiamo una fabbrica che se ne occupi per noi:
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;
}
}
Ora tutto quello che dobbiamo fare è
$factory = new Factory;
$obj = $factory->build();
Il vero vantaggio è quando vuoi cambiare classe. Diciamo che volevamo passare in una ClassC diversa:
class Factory_New extends Factory{
public function buildC(){
return new ClassD;
}
}
o una nuova Classe B:
class Factory_New2 extends Factory{
public function buildB(){
return new ClassE;
}
}
Ora possiamo usare l'ereditarietà per modificare facilmente il modo in cui viene creata la classe, per inserire un diverso insieme di classi.
Un buon esempio potrebbe essere questa classe utente:
class User{
public $data;
public function __construct($data)
{
$this->data = $data;
}
}
In questa classe $data
è la classe che usiamo per memorizzare i nostri dati. Ora per questa classe, diciamo di utilizzare una sessione per memorizzare i nostri dati. La fabbrica sarebbe simile a questa:
class Factory{
public function build()
{
$data = $this->buildData();
return $this->buildUser($data);
}
public function buildData()
{
return SessionObject();
}
public function buildUser($data)
{
return User($data);
}
}
Ora, diciamo invece che vogliamo memorizzare tutti i nostri dati nel database, è davvero semplice cambiarlo:
class Factory_New extends Factory{
public function buildData()
{
return DatabaseObject();
}
}
Le fabbriche sono un modello di progettazione che utilizziamo per controllare il modo in cui mettiamo insieme gli oggetti e l'utilizzo di modelli di fabbrica corretti ci consente di creare gli oggetti personalizzati di cui abbiamo bisogno.
$obj = $factory->build();
rispetto $obj = new whateverClass();
? Inoltre, in un'altra classe (diciamo classZ) che dipende dai dati di classA, dove in classZ useresti il metodo factory? In sostanza stai ancora istanziando una classe (classZ) all'interno di una classe (classA), il che significa nessun test. ad esempio, la fabbrica sembra essere solo un carico di codice da fare new
tramite un metodo invece di usarlo new
.
Come una vera fabbrica, crea qualcosa e lo restituisce.
Immagina qualcosa di simile
$joe = new Joe();
$joe->say('hello');
o un metodo di fabbrica
Joe::Factory()->say('hello');
L'implementazione del metodo factory creerà una nuova istanza e la restituirà.
Il modello di progettazione di fabbrica è molto buono quando si ha a che fare con più risorse e si desidera implementare un'astrazione di alto livello.
Dividiamolo in una sezione diversa.
Supponi di dover implementare l'astrazione e l'utente della tua classe non deve preoccuparsi di ciò che hai implementato nella definizione della classe.
Deve solo preoccuparsi dell'uso dei metodi di classe.
es. hai due database per il tuo progetto
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;
}
}
La tua classe Factory si occuperà della creazione dell'oggetto per la connessione al database.
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;
}
}
L'utente deve solo passare il nome del tipo di database
$dbconn1 = DBFactory::getConn("MySQL");
$dbconn1->select();
Produzione:
MySQL Database Connection
Your mysql select query execute here
In futuro potresti avere un database diverso, quindi non è necessario modificare l'intero codice, è sufficiente passare il nuovo tipo di database e altro codice verrà eseguito senza apportare modifiche.
$dbconn2 = DBFactory::getConn("Oracle");
$dbconn2->select();
Produzione:
Oracle Database Connection
Your oracle select query execute here
Spero che questo ti aiuti.
Una fabbrica genera solo uno o più oggetti.
Potresti avere una fabbrica che crea una connessione MySQL.
Questa risposta è in relazione ad un altro post in cui Daniel White diceva di usare factory per creare una connessione MySQL utilizzando il pattern factory.
Per la connessione MySQL preferirei utilizzare il pattern singleton poiché si desidera utilizzare la stessa connessione per accedere al database e non crearne un altro.
L'approccio classico per istanziare un oggetto è:
$Object=new ClassName();
PHP ha la capacità di creare dinamicamente un oggetto dal nome della variabile utilizzando la seguente sintassi:
$Object=new $classname;
dove la variabile $ classname contiene il nome della classe che si desidera istanziare.
Quindi il factoring di oggetti classico sarebbe simile a:
function getInstance($classname)
{
if($classname==='Customer')
{
$Object=new Customer();
}
elseif($classname==='Product')
{
$Object=new Product();
}
return $Object;
}
e se chiami la funzione getInstance ('Product') questa factory creerà e restituirà l'oggetto Product. Altrimenti, se chiami la funzione getInstance ('Customer'), questa factory creerà e restituirà un oggetto di tipo Customer (creato dalla classe Customer ()).
Non ce n'è più bisogno, è possibile inviare "Prodotto" o "Cliente" (nomi esatti delle classi esistenti) come valore della variabile per l'istanza dinamica:
$classname='Product';
$Object1=new $classname; //this will instantiate new Product()
$classname='Customer';
$Object2=new $classname; //this will instantiate new Customer()
Per la cronaca, in parole semplici, una fabbrica come ha detto @Pindatjuh, restituisce un oggetto.
Allora, qual è la differenza con un costruttore? (che fa lo stesso)
Il costruttore viene chiamato quando viene creata ogni istanza. A volte non lo vuoi.
Ad esempio, diciamo che ogni volta che creo un oggetto della classe Account, leggo dal database un file e lo utilizzo come modello.
Utilizzando il costruttore:
class Account {
var $user;
var $pwd;
var ...
public __construct() {
// here i read from the file
// and many other stuff
}
}
Utilizzando fabbrica:
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;
}