程序员人生 网站导航

PHP设计模式之工厂模式学习笔记

栏目:php教程时间:2014-06-17 01:55:40

本文章来给大家介绍php5中的一个新东西,就是工厂模式了,这里是我常用工厂模式的一些学习笔记,下面与大家一同分享有需要了解的朋友可参考.

在大型系统中,许多代码依赖于少数几个关键类.需要更改这些类时,可能会出现困难.例如,假设您有一个从文件读取的 User 类.您希望将其更改为从数据库读取的其他类,但是,所有的代码都引用从文件读取的原始类.这时候,使用工厂模式会很方便.工厂模式是一种类,它具有为您创建对象的某些方法.您可以使用工厂类创建对象,而不直接使用 new.这样,如果您想要更改所创建的对象类型,只需更改该工厂即可.使用该工厂的所有代码会自动更改.

示例1:显示工厂类的一个示列.

等式的服务器端包括两个部分:数据库和一组 PHP 页面,这些页面允许您添加反馈、请求反馈列表并获取与特定反馈相关的文章

实例代码如下:

  1. <?php 
  2.  interface IUser 
  3.  { 
  4.   function getName(); 
  5.  } 
  6.  class User implements IUser 
  7.  { 
  8.   public function __construct( $id ) { } 
  9.   public function getName() 
  10.   { 
  11.    return "Jack"
  12.   } 
  13.  } 
  14.  class UserFactory 
  15.  { 
  16.   public static function Create( $id ) 
  17.   { 
  18.    return new User( $id ); 
  19.   } 
  20.  } 
  21.  $uo = UserFactory::Create( 1 ); 
  22.  echo$uo->getName()."n" ); 
  23. ?> 

IUser接口定义用户对象应执行什么操作.IUser 的实现称为 User,UserFactory 工厂类则创建 IUser 对象.此关系可以用图1中的UML表示.

图 1. 工厂类及其相关 IUser 接口和用户类如果您使用 php 解释器在命令行上运行此代码,将得到如下结果:

% php factory1.php
Jack
%
 

测试代码会向工厂请求 User 对象,并输出 getName 方法的结果.有一种工厂模式的变体使用工厂方法.类中的这些公共静态方法构造该类型的对象.如果创建此类型的对象非常重要,此方法非常有用.例如,假设您需要先创建对 象,然后设置许多属性.此版本的工厂模式会将该进程封装在单个位置中,这样,不用复制复杂的初始化代码,也不必将复制好的代码在在代码库中到处粘贴.

示例2 显示使用工厂方法的一个示例.

实例代码如下:

  1. <?php 
  2. interface IUser 
  3.   function getName(); 
  4. class User implements IUser 
  5.   public static function Load( $id ) 
  6.   { 
  7.         return new User( $id ); 
  8.   } 
  9.   public static function Create( ) 
  10.   { 
  11.         return new User( null ); 
  12.   } 
  13.   public function __construct( $id ) { } 
  14.   public function getName() 
  15.   { 
  16.     return "Jack"
  17.   } 
  18. $uo = User::Load( 1 ); 
  19. echo$uo->getName()."n" ); 
  20. ?> 

好了上面讲了很多了, 下面我来来看个实例

我们建立以下四个文件

index.php实例代码如下:

  1. <?php 
  2. include_once("f.inc.php"); 
  3. $f=new factory; 
  4. $t1=&$f->create('T1'); 
  5. echo $t1->getName(); 
  6. echo $config
  7. ?> 

f.inc.php实例代码如下:

  1. <?php 
  2. class factory 
  3.  function factory() 
  4.  { 
  5.   $this->mClasses=array 
  6.  
  7. ('T1'=>'t1.inc.php','T2'=>'t2.inc.php'); 
  8.  } 
  9.  function &create($class
  10.  { 
  11.   if (!class_exists($class)) 
  12.   { 
  13.    require_once($this->mClasses[$class]); 
  14.   } 
  15.   return new $class
  16.  } 
  17. ?> 

t1.inc.php实例代码如下:

  1. <?php 
  2. global $config
  3. $config='surfchen'
  4. class T1 
  5.  var $mName='name::T1'
  6.  function getName() 
  7.  { 
  8.   return $this->mName; 
  9.  } 
  10. ?> 

t2.inc.php实例代码如下:

  1. <?php 
  2. class T2 
  3.  function T2() 
  4.  { 
  5.   echo 't2 is ok'
  6.  } 
  7. ?> 

在index.php里,我们通过一个factory类来创建其他的类实例.在factory里,保存有一个数组$this->mClasses,格式为array(“类名”=>”类文件路径”).我们通过factory::create()来创建一个类实例的时候,在create()里,会首先检测类是否存在,如果不存在,就根据$this->mClasses把类对应的类文件包含进来.然后创建并返回一个该类的实例.这样,我们只需要把factory类文件包含进执行的脚本(如index.php)中就可以了.大家可能还注意到了在t1.inc.php中的这两行代码.

实例代码如下:

  1. global $config
  2. $config='surfchen'

为什么需要global呢?因为t1.inc.php是在factory::create中被包含的,t1文件中的变量将会默认为create的函数级变量.所以我们需要对其中的变量(如$config)进行global以便index.php能访问到.运行index.php,将会输出

实例代码如下:

  1. name::T1surfchen 
------分隔线----------------------------
------分隔线----------------------------

最新技术推荐