PHP 中的工厂设计模式是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2083424/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 04:56:37  来源:igfitidea点击:

What is a Factory Design Pattern in PHP?

phpfactories

提问by JasonDavis

This confuses me, in the most simplest terms what does it do? Pretend you are explaining to your mother or someone almost please.

这让我很困惑,用最简单的术语来说它是做什么的?假设您正在向您的母亲或几乎请的人解释。

回答by Tyler Carter

A factory creates an object. So, if you wanted to build

工厂创建一个对象。所以,如果你想建立

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

You wouldn't want to rely on having to do the following code everytime you create the object

您不想依赖于每次创建对象时都必须执行以下代码

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

That is where the factory would come in. We define a factory to take care of that for us:

这就是工厂的用武之地。我们定义了一个工厂来为我们处理这个问题:

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

Now all we have to do is

现在我们要做的就是

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

The real advantage is when you want to change the class. Lets say we wanted to pass in a different ClassC:

真正的优势是当您想要更改课程时。假设我们想传入一个不同的 ClassC:

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

or a new ClassB:

或一个新的 ClassB:

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

Now we can use inheritance to easily modify how the class is created, to put in a different set of classes.

现在我们可以使用继承来轻松修改类的创建方式,以放入不同的类集。

A good example might be this user class:

一个很好的例子可能是这个用户类:

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

In this class $datais the class we use to store our data. Now for this class, lets say we use a Session to store our data. The factory would look like this:

在这个类中$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);
    }
}

Now, lets say instead we want to store all of our data in the database, it is really simple to change it:

现在,假设我们想将所有数据存储在数据库中,更改它非常简单:

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

Factories are a design pattern we use to control how we put objects together, and using correct factory patterns allows us to create the customized objects we need.

工厂是我们用来控制如何将对象组合在一起的设计模式,使用正确的工厂模式可以让我们创建我们需要的自定义对象。

回答by alex

Like a real life factory, it creates something and returns it.

就像一个现实生活中的工厂,它创造了一些东西并返回它。

Imagine something like this

想象一下这样的事情

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

or a factory method

或工厂方法

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

The implementation of the factory method will create a new instance and return it.

工厂方法的实现将创建一个新实例并返回它。

回答by Shailesh Sonare

Factory design pattern is very good when you are dealing with multiple resources and want to implement high level abstraction.

当您处理多个资源并希望实现高级抽象时,工厂设计模式非常有用。

Let's break this into different section.

让我们把它分成不同的部分。

Suppose you have to implement abstraction and the user of your class doesn't need to care about what you've implemented in class definition.

假设您必须实现抽象并且您的类的用户不需要关心您在类定义中实现了什么。

He/She just need to worry about the use of your class methods.

他/她只需要担心您的类方法的使用。

e.g. You have two databases for your project

例如,您的项目有两个数据库

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

}

Your Factory class would take care of the creation of object for database connection.

您的工厂类将负责为数据库连接创建对象。

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

}

User just need to pass the name of the database type

用户只需要传递数据库类型的名称

$dbconn1 = DBFactory::getConn("MySQL");
$dbconn1->select();

Output:

输出:

MySQL Database Connection
Your mysql select query execute here

In future you may have different database then you don't need to change the entire code only need to pass the new database type and other code will run without making any changes.

将来你可能有不同的数据库,那么你不需要更改整个代码只需要传递新的数据库类型,其他代码将在不做任何更改的情况下运行。

$dbconn2 = DBFactory::getConn("Oracle");
$dbconn2->select();

Output:

输出:

Oracle Database Connection
Your oracle select query execute here

Hope this will help.

希望这会有所帮助。

回答by Pindatjuh

In general a "factory" produces something: in the case of Object-Orientated-Programming, a "factory design pattern" produces objects.

一般来说,“工厂”生产一些东西:在面向对象编程的情况下,“工厂设计模式”生产对象。

It doesn't matter if it's in PHP, C# or any other Object-Orientated language.

它是在 PHP、C# 或任何其他面向对象的语言中都没有关系。

回答by N Zhang

Factory Design Pattern (Factory Pattern) is for loose coupling. Like the meaning of factory, data to a factory (produce data) to final user. By this way, the factory break the tight coupling between source of data and process of data.

工厂设计模式(Factory Pattern)是为了松耦合。就像工厂的意思一样,数据到工厂(生产数据)到最终用户。通过这种方式,工厂打破了数据源和数据过程之间的紧密耦合。

回答by Marcin - user2676388

This answer is in relation to other post in which Daniel White said to use factory for creating MySQL connection using factory pattern.

这个答案与 Daniel White 说使用工厂使用工厂模式创建 MySQL 连接的其他帖子有关。

For MySQL connection I would rather use singleton pattern as you want to use same connection for accessing the database not create another one.

对于 MySQL 连接,我宁愿使用单例模式,因为您想使用相同的连接来访问数据库而不是创建另一个连接。

回答by sbrbot

The classic approach to instantiate an object is:

实例化对象的经典方法是:

$Object=new ClassName();

PHP has the ability to dynamically create an object from variable name using the following syntax:

PHP 能够使用以下语法从变量名动态创建对象:

$Object=new $classname;

where variable $classname contains the name of class one wants to instantiate.

其中变量 $classname 包含要实例化的类的名称。

So classic object factoring would look like:

所以经典的对象分解看起来像:

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

and if you call getInstance('Product') function this factory will create and return Product object. Otherwise if you call getInstance('Customer') function this factory will create and return Customer type object (created from Customer() class).

如果您调用 getInstance('Product') 函数,该工厂将创建并返回 Product 对象。否则,如果您调用 getInstance('Customer') 函数,该工厂将创建并返回 Customer 类型对象(从 Customer() 类创建)。

There's no need for that any more, one can send 'Product' or 'Customer' (exact names of existing classes) as a value of variable for dynamic instantiation:

不再需要这样了,可以发送“产品”或“客户”(现有类的确切名称)作为动态实例化的变量值:

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

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

回答by magallanes

For the record, in easy words, a factory like @Pindatjuh said, returns a object.

为了记录,简单地说,像@Pindatjuh 所说的工厂返回一个对象。

So, what's the difference with a constructor? (that does the same)

那么,与构造函数有什么区别呢?(做同样的事情)

  1. a constructor uses his own instance.
  2. Something i want to so something more advanced and i don't want to bloat the object (or add dependencies).
  3. Constructor is called when each instance is created. Sometimes you don't want that.

    For example, let's say that every time i creates an object of the class Account, i read from the database a file and use it as a template.

  1. 构造函数使用他自己的实例。
  2. 我想要一些更高级的东西,我不想膨胀对象(或添加依赖项)。
  3. 创建每个实例时都会调用构造函数。有时你不想那样。

    例如,假设每次我创建 Account 类的对象时,我都会从数据库中读取一个文件并将其用作模板。

Using constructor:

使用构造函数:

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

Using factory:

使用工厂:

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

回答by Daniel A. White

A factory just generates an object or objects.

工厂只生成一个或多个对象。

You may have a factory that builds a MySQL connection.

您可能有一个建立 MySQL 连接的工厂。

http://en.wikipedia.org/wiki/Factory_method_pattern

http://en.wikipedia.org/wiki/Factory_method_pattern