O que é uma Fábrica Padrão de Design em PHP?
Pergunta
Isso confunde-me, na maioria termos mais simples, o que faz?Fingir que você está explicando a sua mãe ou alguém quase por favor.
Solução
Uma fábrica cria um objeto. Então, se você quisesse construir
class A{
public $classb;
public $classc;
public function __construct($classb, $classc)
{
$this->classb = $classb;
$this->classc = $classc;
}
}
Você não gostaria de confiar em ter que fazer o seguinte código toda vez que criar o objeto
$obj = new ClassA(new ClassB, new Class C);
É aí que a fábrica entraria. Definimos uma fábrica para cuidar disso para nós:
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;
}
}
Agora tudo o que temos que fazer é
$factory = new Factory;
$obj = $factory->build();
A verdadeira vantagem é quando você deseja mudar a classe. Digamos que queríamos passar em uma classe diferente:
class Factory_New extends Factory{
public function buildC(){
return new ClassD;
}
}
ou uma nova classe:
class Factory_New2 extends Factory{
public function buildB(){
return new ClassE;
}
}
Agora, podemos usar a herança para modificar facilmente como a classe é criada, para colocar um conjunto diferente de classes.
Um bom exemplo pode ser esta classe de usuário:
class User{
public $data;
public function __construct($data)
{
$this->data = $data;
}
}
Nesta aula $data
é a classe que usamos para armazenar nossos dados. Agora, para esta classe, digamos que usamos uma sessão para armazenar nossos dados. A fábrica ficaria assim:
class Factory{
public function build()
{
$data = $this->buildData();
return $this->buildUser($data);
}
public function buildData()
{
return SessionObject();
}
public function buildUser($data)
{
return User($data);
}
}
Agora, digamos, em vez disso, queremos armazenar todos os nossos dados no banco de dados, é realmente simples alterá -lo:
class Factory_New extends Factory{
public function buildData()
{
return DatabaseObject();
}
}
As fábricas são um padrão de design que usamos para controlar como montamos objetos, e o uso de padrões corretos de fábrica nos permite criar os objetos personalizados de que precisamos.
Outras dicas
Como uma fábrica da vida real, cria algo e a devolve.
Imagine algo assim
$joe = new Joe();
$joe->say('hello');
ou um método de fábrica
Joe::Factory()->say('hello');
A implementação do método da fábrica criará uma nova instância e a devolverá.
O padrão de design de fábrica é muito bom quando você está lidando com vários recursos e deseja implementar a abstração de alto nível.
Vamos dividir isso em seções diferentes.
Suponha que você precise implementar a abstração e o usuário da sua classe não precisa se preocupar com o que você implementou na definição de classe.
Ele/ela só precisa se preocupar com o uso de seus métodos de classe.
por exemplo, você tem dois bancos de dados para o seu projeto
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;
}
}
Sua classe de fábrica cuidaria da criação do objeto para conexão com o banco de dados.
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;
}
}
O usuário só precisa passar o nome do tipo de banco de dados
$dbconn1 = DBFactory::getConn("MySQL");
$dbconn1->select();
Resultado:
MySQL Database Connection
Your mysql select query execute here
No futuro, você pode ter um banco de dados diferente, e não precisará alterar o código inteiro precisar passar apenas o novo tipo de banco de dados e outro código será executado sem fazer alterações.
$dbconn2 = DBFactory::getConn("Oracle");
$dbconn2->select();
Resultado:
Oracle Database Connection
Your oracle select query execute here
Espero que isso ajude.
Em geral, uma "fábrica" produz algo:no caso do Objeto-Orientado-Programação, uma fábrica de "padrão de projeto" produz objetos.
Não importa se é em PHP, C# ou qualquer outro Objeto-Orientado idioma.
O padrão de design da fábrica (padrão de fábrica) é para acoplamento frouxo. Como o significado da fábrica, os dados de uma fábrica (produzem dados) para o usuário final. Dessa forma, a fábrica quebra o acoplamento apertado entre a fonte de dados e o processo de dados.
Uma fábrica gera apenas um objeto ou objetos.
Você pode ter uma fábrica que constrói uma conexão MySQL.
Esta resposta está em relação a outro post em que Daniel White disse usar a fábrica para criar a conexão MySQL usando o padrão de fábrica.
Para a conexão MySQL, prefiro usar o padrão Singleton, pois você deseja usar a mesma conexão para acessar o banco de dados e não criar outro.
A abordagem clássica para instanciar um objeto é:
$Object=new ClassName();
O PHP tem a capacidade de criar dinamicamente um objeto a partir do nome da variável usando a seguinte sintaxe:
$Object=new $classname;
onde a variável $ className contém o nome da classe um deseja instanciar.
Portanto, o fator de objeto clássico seria:
function getInstance($classname)
{
if($classname==='Customer')
{
$Object=new Customer();
}
elseif($classname==='Product')
{
$Object=new Product();
}
return $Object;
}
E se você chamar a função getInstance ('produto'), esta fábrica criará e retornará o objeto do produto. Caso contrário, se você ligar para a função GetInstance ('Cliente'), esta fábrica criará e retornará o objeto do tipo de cliente (criado a partir da classe Customer ().
Não há mais necessidade disso, pode -se enviar 'produto' ou 'cliente' (nomes exatos das classes existentes) como um valor de variável para instanciação dinâmica:
$classname='Product';
$Object1=new $classname; //this will instantiate new Product()
$classname='Customer';
$Object2=new $classname; //this will instantiate new Customer()
Para o registro, em palavras fáceis, uma fábrica como @pindatjuh disse, retorna um objeto.
Então, qual é a diferença com um construtor? (Isso faz o mesmo)
- Um construtor usa sua própria instância.
- Algo que eu quero para algo mais avançado e não quero inchar o objeto (ou adicionar dependências).
O construtor é chamado quando cada instância é criada. Às vezes você não quer isso.
Por exemplo, digamos que toda vez que eu cria um objeto da conta da classe, leio no banco de dados um arquivo e o uso como um modelo.
Usando o construtor:
class Account {
var $user;
var $pwd;
var ...
public __construct() {
// here i read from the file
// and many other stuff
}
}
Usando a 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;
}