这让我感到困惑,用最简单的语言来说它是做什么的?请假设你正在向你的母亲或者一个几乎不懂技术的人解释。
一个工厂创建一个对象。因此,如果您想构建
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;
}
}
或者创建一个新的ClassB:
class Factory_New2 extends Factory{
public function buildB(){
return new ClassE;
}
}
class User{
public $data;
public function __construct($data)
{
$this->data = $data;
}
}
$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);
}
}
假设我们想把所有数据都存储在数据库中,更改起来非常简单:
class Factory_New extends Factory{
public function buildData()
{
return DatabaseObject();
}
}
工厂模式是一种设计模式,我们用它来控制如何组合对象,使用正确的工厂模式允许我们创建需要的定制化对象。
$obj = $factory->build();
相对于 $obj = new whateverClass();
有什么不同/好处?另外,在另一个依赖于 classA 数据的类(比如 classZ)中,你会在哪里使用工厂方法?实际上你仍然是在一个类(classA)中实例化另一个类(classZ),这意味着没有测试。例如,工厂似乎只是通过方法执行 new
而不是直接使用 new
的一堆代码。 - James工厂设计模式非常适合处理多个资源并实现高级抽象。
让我们将其分成不同的部分。
假设您必须实现抽象化,而类的用户不需要关心您在类定义中实现了什么。
他/她只需担心类方法的使用。
例如,您的项目有两个数据库。
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
希望这能有所帮助。
就像一个真实的工厂,它会创建某些东西并返回它。
想象一下这样的场景:
$joe = new Joe();
$joe->say('hello');
或者一个工厂方法
Joe::Factory()->say('hello');
工厂方法的实现将创建一个新实例并返回它。
$Object=new ClassName();
PHP具有使用以下语法从变量名动态创建对象的能力:
$Object=new $classname;
变量$classname包含要实例化的类名。
因此,经典的对象工厂看起来像:
function getInstance($classname)
{
if($classname==='Customer')
{
$Object=new Customer();
}
elseif($classname==='Product')
{
$Object=new Product();
}
return $Object;
}
如果您调用getInstance('Product')函数,则该工厂将创建并返回Product对象。否则,如果您调用getInstance('Customer')函数,则该工厂将创建并返回客户类型对象(由Customer()类创建)。
现在不再需要这样做,可以将“Product”或“Customer”(现有类的确切名称)作为变量值发送以进行动态实例化:
$classname='Product';
$Object1=new $classname; //this will instantiate new Product()
$classname='Customer';
$Object2=new $classname; //this will instantiate new Customer()
工厂设计模式(Factory Pattern)是为了实现松耦合。就像工厂的意义一样,数据被送到工厂(生产数据),最终用户使用。通过这种方式,工厂打破了数据源和数据处理之间的紧耦合。
这个回答是针对另一篇帖子的,其中Daniel White建议使用工厂模式来创建MySQL连接。
对于MySQL连接,我更倾向于使用单例模式,因为您想要使用相同的连接来访问数据库而不是创建另一个连接。
工厂是一种解决应用程序代码易于维护和可扩展性的解决方案。它解决了SOLID建议我们遵循的代码耦合问题。本质上,它是简化结构的构建/创建的一种方式。它可以是对象、函数或数组。
只要您将使用结构的代码与创建它们的代码分离,并返回对象/结构,您就正在使用工厂,其中可以是以下四个之一:
主要区别在于工厂方法和抽象工厂。
一个从定义良好的元素列表生成对象/结构,另一个使用自己的制造策略生成对象的蓝图。
一个生成具体元素,另一个生成类型。
就记录而言,简单地说,像@Pindatjuh所说的工厂会返回一个对象。
那么,与构造函数有什么区别呢?(二者做的事情相同)
每创建一个实例时都会调用构造函数。 有时您不希望如此。
例如,假设每次我创建一个类Account的对象时,我都会从数据库中读取文件并将其用作模板。
使用构造函数:
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;
}