[转]PHP 中实现 Factory 模式

转自:http://blog.chinaunix.net/u/10599/showart_329537.html

有这么一种观点:似乎没有 “Factory 模式”一说,GoF 的 23 个模式中与 Factory 相关的有两个:Factory Method 和 Abstract Factory ,《深入浅出设计模式》中则定义了一个 Simple Factory 模式。而本人( Hick ) 翻阅了一下相关资料,Robert C. Martin 的《Agile Software Development: Principles, Patterns, and Pracitces》直接提的是“Factory 模式”。具体情况有兴趣的可以去详细考证。

“Factory 模式允许我们之依赖于抽象接口就能够创建出具体对象的实例”,是 DIP (依赖倒置原则)的体现。我们能够通过给一个工厂(factory)不同的需求来生产不同但是相似的产品(实例化对象)。

嘿嘿,人说,最好的文档就是代码。我不仅仅这样说,我还可以证明给你看(在这里的显示效果不好,建议拷贝到 PHP 编辑器中看),下面分别是《PHP 手册》、《Core PHP Programming》和《PHP 5 Power Programming》中 Factory 模式的实例解析:

<?php
/**
* factory 模式
*
* factory 的概念不像 Singleton 等模式那样, factory 模式比较
* 灵活。通常根据不同的要求能够"生产不同对象"(实例化类)就可以
* 归为 factory 模式或者其变体。
*/

/**
* 先用手册中一个简单的例子说明 factory 模式
*
* 注意下面这段代码并不可执行,因为需要定义相应的数据库[Driver]类。
*/

class DbFactory
{
  
// factory 方法
  
public static function factory($type)
  
{
  
// 注意这里的包含文件应该是相关数据库的[Driver]类
  
if (include_once Drivers/ . $type . .php) {
  
$classname = Driver_ . $type;
  
return new $classname;
  
} else {
  
throw new Exception (Driver not found);
  
}
  
}
}

// 生成数据库(MySQL)连接对象,
$DbCon = DbFactory::factory(MySQL);
// $DbCon = DbFactory::factory(‘SQLite’);

/**
* "Core PHP Programming" 中的例子
*/

class Factory
{
  
private $registeredClasses = array();
  
  
static private $instance = NULL;

   private function __construct() {}

   static function getInstance()
  
{
  
if(self::$instance == NULL)
  
{
  
self::$instance = new Factory();
  
}
  
return self::$instance;
  
}

   function registerClass($id, $creator_func)
  
{
  
$this->registeredClasses[$id] = $creator_func;
  
}

   function createObject($id, $args)
  
{
  
if(!isset($this->registeredClasses[$id]))
  
{
  
return(NULL);
  
}
  
return($this->registeredClasses[$id]($args));
  
}
}

class MyClass
{
  
private $created;
  
public function __construct()
  
{
  
$created = time();
  
}

   public function getCreated()
  
{
  
return($this->created);
  
}
}

function MyClassCreator()
{
  
return(new MyClass());
}

$factory = Factory::getInstance();
$factory->registerClass(1234, "MyClassCreator");
$instance = $factory->createObject(1234, array());

/**
* "PHP 5 Power Programming" 中的对 factory 模式的诠释
*
* 一个 Factory 类通常都有一个方法负责接受参数,根据参数的不同来决定
* "生产"哪个类的实例。下面拿网站的用户作为例子,作为实际运用:把网站
* 用户分成匿名用户,普通(注册)用户,管理员。我们在类中进行用户的权限
* 控制—这样能够更好的展现 factory 类在整个类体系中所扮演的角色。
*/

/**
* 基类 User
*/

abstract class User
{
  
public $name = null;
  
  
public function __construct($name)
  
{
  
$this->name = $name;
  
}
  
  
function getName()
  
{
  
return $this->name;
  
}
  
  
// 权限控制方法
  
function hasReadPermission()
  
{
  
return true;
  
}
  
  
function hasModifyPermission()
  
{
  
return false;
  
}
  
  
function hasDeletePermission()
  
{
  
return false;
  
}
}

// 匿名用户类
class GuestUser extends User
{}

// 注册用户类
class CustomerUser extends User
{
  
function hasModifyPermission()
  
{
  
return true;
  
}
}

// 管理员类
class AdminUser extends User {
  
function hasModifyPermission()
  
{
  
return true;
  
}

   function hasDeletePermission()
  
{
  
return true;
  
}
}

/**
* 用户 factory 类
*/

class UserFactory {
  
private static $users =
  
array("Andi"=>"admin", "Hick"=>"guest",
  
"Derick"=>"customer");

   static function Create($name)
  
{
  
if (!isset(self::$users[$name])) {
  
// 如果不存在对应的用户类,则提示错误
  
}
  
switch (self::$users[$name]) {
  
case "guest": return new GuestUser($name);
  
case "customer": return new CustomerUser($name);
  
case "admin": return new AdminUser($name);
  
default: // 默认应该报错
  
}
  
}
}

// 使用 factory 类实例化用户
$HickUser = UserFactory::Create(Hick);
echo $HickUser->name;
?>

Read: 851

发表评论

电子邮件地址不会被公开。 必填项已用*标注