用最简单的话来说,这让我感到困惑。假装您几乎在向母亲或某人解释。
Answers:
工厂创建一个对象。所以,如果你想建立
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();
真正的优势在于您想更改班级。可以说我们想传入另一个ClassC:
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)中,您将在classZ中的工厂方法中使用什么位置?从本质上讲,您仍在实例化类(classA)中的类(classZ),这意味着无需进行测试。例如工厂似乎是new
通过方法而不是仅使用方法来加载的代码new
。
就像现实生活中的工厂一样,它创建并返回东西。
想象这样的事情
$joe = new Joe();
$joe->say('hello');
或工厂方法
Joe::Factory()->say('hello');
工厂方法的实现将创建一个新实例并返回它。
当您处理多种资源并想要实现高级抽象时,工厂设计模式非常好。
让我们将其分为不同的部分。
假设您必须实现抽象,并且类的用户不需要关心在类定义中实现的内容。
他/她只需要担心您的类方法的使用。
例如,您的项目有两个数据库
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;
}
}
您的Factory类将负责创建数据库连接对象。
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
希望这会有所帮助。
这个答案与其他帖子有关,丹尼尔·怀特(Daniel White)曾说过使用工厂使用工厂模式创建MySQL连接。
对于MySQL连接,我宁愿使用单例模式,因为您想使用相同的连接来访问数据库,而不要创建另一个连接。
实例化对象的经典方法是:
$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类型对象(从Customer()类创建)。
不再需要,可以将“产品”或“客户”(现有类的确切名称)作为变量的值发送给动态实例化:
$classname='Product';
$Object1=new $classname; //this will instantiate new Product()
$classname='Customer';
$Object2=new $classname; //this will instantiate new Customer()
为了便于记录,@ 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;
}