PHP设计模式之工厂模式学习笔记
在大型系统中,许多代码依赖于少数几个关键类。需要更改这些类时,可能会出现困难。例如,假设您有一个从文件读取的 User 类。您希望将其更改为从数据库读取的其他类,但是,所有的代码都引用从文件读取的原始类。这时候,使用工厂模式会很方便。
工厂模式是一种类,它具有为您创建对象的某些方法。您可以使用工厂类创建对象,而不直接使用 new。这样,如果您想要更改所创建的对象类型,只需更改该工厂即可。使用该工厂的所有代码会自动更改。
示例1:显示工厂类的一个示列。
等式的服务器端包括两个部分:数据库和一组 PHP 页面,这些页面允许您添加反馈、请求反馈列表并获取与特定反馈相关的文章
<table width="620" align="center" border="0" cellpadding="1" cellspacing="1" style="background:#FB7"> <tr> <td width="464" height="27" bgcolor="#FFE7CE"> 代码如下</td> <td width="109" align="center" bgcolor="#FFE7CE" style="cursor:pointer;" onclick="doCopy('copy8818')">复制代码</td> </tr> <tr> <td height="auto" colspan="2" valign="top" bgcolor="#FFFFFF" style="padding:10px;" class="copyclass" id=copy8818><?php
interface IUser
{
function getName();
}
class User implements IUser
{
public function __construct( $id ) { }
public function getName()
{
return "Jack";
}
}
class UserFactory
{
public static function Create( $id )
{
return new User( $id );
}
}
$uo = UserFactory::Create( 1 );
echo( $uo->getName()."n" );
?>
IUser接口定义用户对象应执行什么操作。IUser 的实现称为 User,UserFactory 工厂类则创建 IUser 对象。此关系可以用图1中的UML 表示。
图 1. 工厂类及其相关 IUser 接口和用户类
如果您使用 php 解释器在命令行上运行此代码,将得到如下结果:
% php factory1.php
Jack
%
测试代码会向工厂请求 User 对象,并输出 getName 方法的结果。
有 一种工厂模式的变体使用工厂方法。类中的这些公共静态方法构造该类型的对象。如果创建此类型的对象非常重要,此方法非常有用。例如,假设您需要先创建对 象,然后设置许多属性。此版本的工厂模式会将该进程封装在单个位置中,这样,不用复制复杂的初始化代码,也不必将复制好的代码在在代码库中到处粘贴。
示例2 显示使用工厂方法的一个示例。
<table width="620" align="center" border="0" cellpadding="1" cellspacing="1" style="background:#FB7"> <tr> <td width="464" height="27" bgcolor="#FFE7CE"> 代码如下</td> <td width="109" align="center" bgcolor="#FFE7CE" style="cursor:pointer;" onclick="doCopy('copy3599')">复制代码</td> </tr> <tr> <td height="auto" colspan="2" valign="top" bgcolor="#FFFFFF" style="padding:10px;" class="copyclass" id=copy3599><?php
interface IUser
{
function getName();
}
class User implements IUser
{
public static function Load( $id )
{
return new User( $id );
}
public static function Create( )
{
return new User( null );
}
public function __construct( $id ) { }
public function getName()
{
return "Jack";
}
}
$uo = User::Load( 1 );
echo( $uo->getName()."n" );
?>
好了上面讲了很多了, 下面我来来看个实例
我们建立以下四个文件
index.php
<table width="620" align="center" border="0" cellpadding="1" cellspacing="1" style="background:#FB7"> <tr> <td width="464" height="27" bgcolor="#FFE7CE"> 代码如下</td> <td width="109" align="center" bgcolor="#FFE7CE" style="cursor:pointer;" onclick="doCopy('copy8736')">复制代码</td> </tr> <tr> <td height="auto" colspan="2" valign="top" bgcolor="#FFFFFF" style="padding:10px;" class="copyclass" id=copy8736><?php
include_once("f.inc.php");
$f=new factory;
$t1=&$f->create('T1');
echo $t1->getName();
echo $config;
?>
f.inc.php
<table width="620" align="center" border="0" cellpadding="1" cellspacing="1" style="background:#FB7"> <tr> <td width="464" height="27" bgcolor="#FFE7CE"> 代码如下</td> <td width="109" align="center" bgcolor="#FFE7CE" style="cursor:pointer;" onclick="doCopy('copy5871')">复制代码</td> </tr> <tr> <td height="auto" colspan="2" valign="top" bgcolor="#FFFFFF" style="padding:10px;" class="copyclass" id=copy5871><?php
class factory
{
function factory()
{
$this->mClasses=array('T1'=>'t1.inc.php','T2'=>'t2.inc.php');
}
function &create($class)
{
if (!class_exists($class))
{
require_once($this->mClasses[$class]);
}
return new $class;
}
}
?>
t1.inc.php
<table width="620" align="center" border="0" cellpadding="1" cellspacing="1" style="background:#FB7"> <tr> <td width="464" height="27" bgcolor="#FFE7CE"> 代码如下</td> <td width="109" align="center" bgcolor="#FFE7CE" style="cursor:pointer;" onclick="doCopy('copy7684')">复制代码</td> </tr> <tr> <td height="auto" colspan="2" valign="top" bgcolor="#FFFFFF" style="padding:10px;" class="copyclass" id=copy7684><?php
global $config;
$config='surfchen';
class T1
{
var $mName='name::T1';
function getName()
{
return $this->mName;
}
}
?>
t2.inc.php
<table width="620" align="center" border="0" cellpadding="1" cellspacing="1" style="background:#FB7"> <tr> <td width="464" height="27" bgcolor="#FFE7CE"> 代码如下</td> <td width="109" align="center" bgcolor="#FFE7CE" style="cursor:pointer;" onclick="doCopy('copy5356')">复制代码</td> </tr> <tr> <td height="auto" colspan="2" valign="top" bgcolor="#FFFFFF" style="padding:10px;" class="copyclass" id=copy5356><?php
class T2
{
function T2()
{
echo 't2 is ok';
}
}
?>
在index.php里,我们通过一个factory类来创建其他的类实例。
在factory里,保存有一个数组$this->mClasses,格式为array(“类名”=>”类文件路径”).
我们通过factory::create()来创建一个类实例的时候,在create()里,会首先检测类是否存在,如果不存在,就根据$this->mClasses把类对应的类文件包含进来。然后创建并返回一个该类的实例。
这样,我们只需要把factory类文件包含进执行的脚本(如index.php)中就可以了。
大家可能还注意到了在t1.inc.php中的这两行代码。
<table width="620" align="center" border="0" cellpadding="1" cellspacing="1" style="background:#FB7"> <tr> <td width="464" height="27" bgcolor="#FFE7CE"> 代码如下</td> <td width="109" align="center" bgcolor="#FFE7CE" style="cursor:pointer;" onclick="doCopy('copy8928')">复制代码</td> </tr> <tr> <td height="auto" colspan="2" valign="top" bgcolor="#FFFFFF" style="padding:10px;" class="copyclass" id=copy8928>global $config;$config='surfchen';
为什么需要global呢?因为t1.inc.php是在factory::create中被包含的,t1文件中的变量将会默认为create的函数级变量。所以我们需要对其中的变量(如$config)进行global以便index.php能访问到。
运行index.php,将会输出
<table width="620" align="center" border="0" cellpadding="1" cellspacing="1" style="background:#FB7"> <tr> <td width="464" height="27" bgcolor="#FFE7CE"> 代码如下</td> <td width="109" align="center" bgcolor="#FFE7CE" style="cursor:pointer;" onclick="doCopy('copy9645')">复制代码</td> </tr> <tr> <td height="auto" colspan="2" valign="top" bgcolor="#FFFFFF" style="padding:10px;" class="copyclass" id=copy9645>name::T1surfchen您可能感兴趣的文章:
深入php设计模式实例详解
php工厂模式实例代码
java工厂模式的学习笔记
java设计模式之抽象工厂模式实例
php常用的三种设计模式的学习笔记
PHP设计模式之:原型模式学习笔记
php常用设计模式之工厂模式与单例模式介绍
JavaScript 设计模式读书笔记(五)——工厂模式
php设计模式是什么,该如何理解
php精粹 php设计模式