代码之家  ›  专栏  ›  技术社区  ›  JasonDavis

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

  •  81
  • JasonDavis  · 技术社区  · 15 年前

    这让我很困惑,用最简单的术语来说,它是做什么的?假装你是在向你的母亲或其他人解释。

    9 回复  |  直到 7 年前
        1
  •  165
  •   Vitalii Zurian odrac1r    11 年前

    工厂创建对象。所以,如果你想建造

     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();
    

    真正的优势是当你想改变课堂。假设我们想通过一个不同的班级:

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

    或新的B类:

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

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

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

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

    在这个班里 $data 是我们用来存储数据的类。对于这个类,假设我们使用一个会话来存储数据。工厂看起来像这样:

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

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

        2
  •  18
  •   alex    15 年前

    就像一个真实的工厂,它创造了一些东西并将其归还。

    想象一下这样的事情

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

    或工厂方法

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

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

        3
  •  4
  •   Shailesh Sonare    7 年前

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

    让我们把这个分成不同的部分。

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

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

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

    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
    

    希望这会有所帮助。

        4
  •  1
  •   Pindatjuh    15 年前

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

    不管是使用PHP、C语言还是其他面向对象的语言。

        5
  •  1
  •   N Zhang    12 年前

    工厂设计模式(工厂模式)用于松耦合。像工厂的意义一样,数据到工厂(生产数据)到最终用户。这样,工厂就打破了数据源和数据处理之间的紧密耦合。

        6
  •  0
  •   Daniel A. White    15 年前

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

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

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

        7
  •  0
  •   Marcin - user2676388    11 年前

    这个答案与丹尼尔·怀特在其他文章中提到的使用工厂模式创建MySQL连接有关。

    对于mysql连接,我宁愿使用singleton模式,因为您希望使用相同的连接 用于访问数据库而不是创建另一个数据库。

        8
  •  0
  •   sbrbot    9 年前

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

    $Object=new ClassName();
    

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

    $Object=new $classname;
    

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

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

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

    如果调用getInstance(“product”)函数,则此工厂将创建并返回product对象。否则,如果调用getInstance(“customer”)函数,则此工厂将创建并返回customer类型对象(从customer()类创建)。

    不再需要这样做,可以将“product”或“customer”(现有类的确切名称)作为变量值发送给动态实例化:

    $classname='Product';
    $Object1=new $classname; //this will instantiate new Product()
    
    $classname='Customer';
    $Object2=new $classname; //this will instantiate new Customer()
    
        9
  •  0
  •   magallanes    9 年前

    简单来说,像@pindatjuh这样的工厂会返回一个对象。

    那么,构造函数有什么区别呢?(也一样)

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

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

    使用构造函数:

    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;
          }
    
    推荐文章