2010-01-18 15 views
76

Esto me confunde, en los términos más simples, ¿qué hace? Imagina que le estás explicando a tu madre o a alguien casi por favor.¿Qué es un patrón de diseño de fábrica en PHP?

+105

Mi madre no lo entendería de todas formas ... –

+6

@JasonDavis guardo responder a sus preguntas ... I' Estoy empezando a sentirme como un acosador. –

Respuesta

159

Una fábrica crea un objeto. Por lo tanto, si usted quiere construir

class A{ 
    public $classb; 
    public $classc; 
    public function __construct($classb, $classc) 
    { 
     $this->classb = $classb; 
     $this->classc = $classc; 
    } 
    } 

Usted no quiere depender de tener que hacer el siguiente código cada vez que se crea el objeto

$obj = new ClassA(new ClassB, new Class C); 

Eso es donde la fábrica vendría. Nos definir una fábrica para hacerse cargo de eso para nosotros:

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; 
    } 
} 

Ahora todo lo que tenemos que hacer es

$factory = new Factory; 
$obj  = $factory->build(); 

La verdadera ventaja es cuando desea cambiar la clase. Digamos que queríamos pasar en un ClassC diferente:

class Factory_New extends Factory{ 
    public function buildC(){ 
     return new ClassD; 
    } 
} 

o un nuevo ClassB:

class Factory_New2 extends Factory{ 
    public function buildB(){ 
     return new ClassE; 
    } 
} 

Ahora podemos utilizar la herencia para modificar fácilmente cómo se crea la clase, para poner en un conjunto diferente de clases

Un buen ejemplo podría ser esta clase de usuario:

class User{ 
    public $data; 
    public function __construct($data) 
    { 
     $this->data = $data; 
    } 
} 

En esta clase $data es la clase que utilizamos para almacenar nuestros datos. Ahora para esta clase, digamos que usamos una sesión para almacenar nuestros datos.La fábrica se vería así:

class Factory{ 
    public function build() 
    { 
     $data = $this->buildData(); 
     return $this->buildUser($data); 
    } 

    public function buildData() 
    { 
     return SessionObject(); 
    } 

    public function buildUser($data) 
    { 
     return User($data); 
    } 
} 

Ahora, digamos que en lugar queremos almacenar todos nuestros datos en la base de datos, es muy simple para cambiarlo:

class Factory_New extends Factory{ 
    public function buildData() 
    { 
     return DatabaseObject(); 
    } 
} 

fábricas son un diseño patrón que utilizamos para controlar cómo unimos los objetos, y el uso de patrones de fábrica correctos nos permite crear los objetos personalizados que necesitamos.

+10

+1 gran ejemplo – Parrots

+2

Eso fue mucha escritura. Ahora tendré que ponerlo en mi wiki en algún momento. –

+0

gracias eso ayuda un poco – JasonDavis

16

como una fábrica de la vida real, se crea algo y lo devuelve.

imaginar algo como esto

$joe = new Joe(); 
$joe->say('hello'); 

o un método de fábrica

Joe::Factory()->say('hello'); 

La aplicación del método de fábrica creará una nueva instancia y devolverlo.

+1

Buen ejemplo, me sorprende cuán variadas son las implementaciones para este patrón. Cuando se llama estáticamente, supongo que uno puede obtener una referencia a la instancia para reutilizar la misma instancia más adelante? es decir $ joe = Joe :: Factory() -> say ('hola'); – stefgosselin

+0

ciertamente como en 5.6 también se puede hacer (nuevo Joe()) -> decir ('hola'); – Pancho

1

En general, una "fábrica" ​​produce algo: en el caso de la programación orientada a objetos, un "patrón de diseño de fábrica" ​​produce objetos.

No importa si está en PHP, C# o cualquier otro lenguaje orientado a objetos.

1

Patrón de diseño de fábrica (Patrón de fábrica) es para acoplamiento flojo. Al igual que el significado de fábrica, los datos a una fábrica (producir datos) para el usuario final. De esta manera, la fábrica rompe el estrecho acoplamiento entre la fuente de datos y el proceso de datos.

0

Esta respuesta está relacionada con otra publicación en la que Daniel White dijo que usara la fábrica para crear una conexión MySQL usando el patrón de fábrica.

Para la conexión de MySQL Prefiero utilizar el patrón de singleton, ya que desea utilizar la misma conexión para acceder a la base de datos y no crear otra.

0

El enfoque clásico para crear instancias de un objeto es:

$Object=new ClassName(); 

PHP tiene la capacidad de crear dinámicamente un objeto del nombre de la variable utilizando la siguiente sintaxis:

$Object=new $classname; 

donde la variable $ nombre de clase contiene el nombre de la clase uno quiere crear una instancia.

Así clásico factoring objeto se vería así:

function getInstance($classname) 
{ 
    if($classname==='Customer') 
    { 
    $Object=new Customer(); 
    } 
    elseif($classname==='Product') 
    { 
    $Object=new Product(); 
    } 
    return $Object; 
} 

y si se llama a la función getInstance ('producto') esta fábrica va a crear y devolver objetos del producto. De lo contrario, si llama a la función getInstance ('Cliente') esta fábrica creará y devolverá el tipo de objeto del cliente (creado desde la clase Cliente()).

No hay necesidad de eso nunca más, se puede enviar 'producto' o 'Cliente' (los nombres exactos de las clases existentes) como un valor de la variable para la instanciación dinámica:

$classname='Product'; 
$Object1=new $classname; //this will instantiate new Product() 

$classname='Customer'; 
$Object2=new $classname; //this will instantiate new Customer() 
0

Para el registro, en palabras fáciles, una fábrica como @Pindatjuh dijo, devuelve un objeto.

Entonces, ¿cuál es la diferencia con un constructor? (que hace lo mismo)

  1. un constructor utiliza su propia instancia.
  2. Algo que quiero algo más avanzado y no quiero hinchar el objeto (o agregar dependencias).
  3. Se llama al constructor cuando se crea cada instancia. A veces no quieres eso.

    Por ejemplo, supongamos que cada vez que creo un objeto de la clase Cuenta, leo de la base de datos un archivo y lo uso como plantilla.

Usando constructor:

class Account { 
     var $user; 
     var $pwd; 
     var ... 
     public __construct() { 
     // here i read from the file 
     // and many other stuff 
     } 
} 

El uso de la fábrica:

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; 
     } 
Cuestiones relacionadas