设计模式之 工厂模式

在面向对象的编程中,工厂模式是一种经常被使用到的模式。根据工厂模式实现的类可以根据提供的数据生成一组类中某一个类的实例,通常这一组类有一个公共的抽象父类并且实现了相同的方法,但是这些方法针对不同的数据进行了不同的操作。工厂类是指包含一个专门用来创建其他对象的方法的类,工厂类在多态性编程实践中是至关重要的。

工厂模式的原理

 

为了理解工厂模式是如果工作的,让我们来看一下图一:
 

 

 


图1 工厂模式的工作原理


在 图1中,X是基类,Xy和Xz继承了X类。而工厂类能够根据程序传递给它的数据决定生成那一个子类的实例。在右边定义了一个getClass方法,该方法 需要参数a并返回一个X类的实例。对于程序员来说,返回的究竟是Xy还是Xz的实例并不重要,因为它们有相同的方法,只不过这些方法的内部实现不同罢了。

/**
* 工厂模式通常含有以下几个三个内容:
* 1. 一个静态的工厂方法。相当于一个选择器。
* 2. 一个接口(或者一个抽象类)。
* 3. 几个不同的接口实现类。
*/


/*
*实例1: 根据不同的数据库类型,创建不同的数据库链接方法
*/


//工厂类,相当一个的选择器,由它来选择创建哪个数据库链接类
class DBFactory{
public static function create($type){
$class = $type."DB";
return new $class;
}
}

//接口,不同的数据库类都要实现connect()和exec()这两个方法
interface DB{
public function connect();
public function exec();
}

//mysql数据库类,DB接口的一个具体实现
class MysqlDB implements DB{
public function __construct(){
echo "mysql DB<br>";
}
public function connect(){
// mysql数据库链接代码....
}
public function exec(){

}
}

//Postgre数据库类
class PostgreDB implements DB{
public function __construct(){
echo "Postgre DB<br>";
}
public function connect(){
// Postgre 数据库链接代码....
}
public function exec(){

}

}

//Mssql 数据库类
class MssqlDB implements DB{
public function __construct(){
echo "Mssql DB<br>";
}
public function connect(){
// Mssql 数据库链接代码....
}
public function exec(){

}
}

// 主程序
$oMysql = DBFactory::create("mysql");
$oPostgre = DBFactory::create("Postgre");
$oMssql = DBFactory::create("Mssql");




/*
* 实例2. 用户权限
* 一个管理系统对于访问用户的权限设置是不同的。
* 对于普通用户仅拥有一般的浏览权限,对于管理员拥有对数据的修改和删除权限,对于维护人员拥有访问用户的授权权即用等。
*/


//工厂类,用于选择创建相应的类
class Facotry{
private static $user = array( //静态成员属性
'Simon' => 'Client',
'Elaine'=> 'Administrator',
'Bob' => 'Supporter'
);

static function Create($name){ //创建对象的成员方法
switch(self::$user[$name]){
case 'Client':
return new Client($name);
case 'Administrator':
return new Administrator($name);
case 'Supporter':
return new Supporter($name);
}
}
}

// 抽象基类
abstract class User{
protected $name = NULL;
function __construct($name){
$this->name = $name;
}
public function getName(){ //获取属性$name
return $this->name;
}
public function ViewAccess(){ //是否具有浏览权限
return 'No';
}
public function EditAccess(){ //是否具有编辑权限
return 'No';
}
public function DeleteAccess(){ //是否具有删除权限
return 'No';
}
public function ManageAccess(){ //是否具有用户管理权限
return 'No';
}
}

// 普通用户,基类的子类
class Client extends User{
public function ViewAccess(){
return 'Yes';
}
}

// 管理员
class Administrator extends User{
public function ViewAccess(){
return 'Yes';
}
public function EditAccess(){
return 'Yes';
}
public function DeleteAccess(){
return 'Yes';
}
}

//维护人员
class Supporter extends User{
public function ViewAccess(){
return 'Yes';
}
public function EditAccess(){
return 'Yes';
}
public function DeleteAccess(){
return 'Yes';
}
public function ManageAccess(){
return 'Yes';
}
}


//主程序

$users = array('Elaine','Simon','Bob');
//对于每个用户分析 其权限
foreach ($users as $user) {
$obj = Facotry::Create($user);
echo $obj->getName().'的权限:<br>';
echo '浏览:'.$obj->ViewAccess().'<Br>';
echo '修改:'.$obj->EditAccess().'<Br>';
echo '删除:'.$obj->DeleteAccess().'<Br>';
echo '管理:'.$obj->ManageAccess().'<Br><Br>';


// 工厂模式体现了面向对象程序设计中的多态。





  工厂模式适用范围:

  • 在编码时不能预见需要创建那一种类的实例
  • 一个类使用它的子类来创建对象
  • 开发人员不希望创建了哪个类的实例以及如何创建实例的信息暴露给外部程序



 

//参考: http://wenku.baidu.com/view/3c64bdcd05087632311212d3.html ;   
//         http://www.cnblogs.com/bluefrog/archive/2011/01/04/1925932.html
//         http://qbye.blog.163.com/blog/static/374535182011827102511542/

posted @ 2012-03-13 17:28  TECS27  阅读(156)  评论(0编辑  收藏  举报