CleverCode最近在看抽象工厂模式。
1 模式介绍
为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。
2 模式中的角色
3 模式结构
4 项目应用
4.1 客户可以根据自己的需求选择sqlserver数据库或者access数据库
4.2 类图.
4.3 php源码
<?php
/**
* 抽象工厂模式
* copyright (c) http://blog.csdn.net/CleverCode
*/
class User
{/*{{{*/
public $id;
public $name;
public function __construct($id,$name)
{
$this->id = $id;
$this->name = $name;
}
public function setId($id)
{
$this->id = $id;
}
public function getId()
{
return $this->id;
}
public function setName($name)
{
$this->name = $name;
}
public function getName()
{
return $this->name;
}
}/*}}}*/
//操作User表
class SqlServerUser
{/*{{{*/
public function insert(User $user)
{
echo "SqlServer 向用户表插入一天记录。id:{$user->id},name:{$user->name}\r\n";
}
public function getUser($id)
{
echo "SqlServer 获取用户id:{$id}记录\r\n";
}
}/*}}}*/
class AccessUser
{/*{{{*/
public function insert(User $user)
{
echo " Access 向数据库用户表插入一天记录。id:{$user->id},name:{$user->name}\r\n";
}
public function getUser($id)
{
echo " Access 获取用户id:{$id}记录\r\n";
}
}/*}}}*/
//部门表
class Dept
{/*{{{*/
public $id;
public $name;
public function __construct($id,$name)
{
$this->id = $id;
$this->name = $name;
}
public function setId($id)
{
$this->id = $id;
}
public function getId()
{
return $this->id;
}
public function setName($name)
{
$this->name = $name;
}
public function getName()
{
return $this->name;
}
}/*}}}*/
class SqlServerDept
{/*{{{*/
public function insert(Dept $dept)
{
echo "SqlServer 部门插入一天记录。id:{$dept->id},name:{$user->dept}\r\n";
}
public function getUser($id)
{
echo "SqlServer 获取部门id:{$id}记录\r\n";
}
}/*}}}*/
class AccessDept
{/*{{{*/
public function insert(Dept $dept)
{
echo " Access 部门表表插入一天记录。id:{$user->id},name:{$user->name}\r\n";
}
public function getUser($id)
{
echo " Access 获取部门id:{$id}记录\r\n";
}
}/*}}}*/
//抽象工厂
abstract class DataOperate
{/*{{{*/
abstract public function createUser();
abstract public function createDept();
}/*}}}*/
//具体工厂access
class DataAccess extends DataOperate
{/*{{{*/
public function createUser()
{
return new AccessUser();
}
public function createDept()
{
return new AccessDept();
}
}/*}}}*/
//具体工厂SqlServer
class DataSqlServer extends DataOperate
{/*{{{*/
public function createUser()
{
return new SqlServerUser();
}
public function createDept()
{
return new SqlServerDept();
}
}/*}}}*/
class Client
{/*{{{*/
//客户选择的db
public static function getDataOperate($db)
{
$dataOperate = null;
switch($db)
{
case 'Access':
$dataOperate = new DataAccess();
break;
case 'SqlServer':
$dataOperate = new DataSqlServer();
break;
}
return $dataOperate;
}
public static function main($argv)
{
//客户选择db
$dataOperate = self::getDataOperate('Access');
//插入一个新的用户
$user = new User(1,'张三');
$userDb = $dataOperate->createUser();
$userDb->insert($user);
}
}/*}}}*/
Client::main($argv);
?>
4.4 结果展示
5 抽象工厂的改进
从上面的代码中可以看到,如果再增加一个mysql数据库,那么就会有一个具体的工厂。getOpersonData中的switch,就得加上一个分支。这里考虑使用反射技术,其中配置文件可以和反射配合使用。
改进源码如下。
<?php
/**
* 抽象工厂模式
* copyright (c) http://blog.csdn.net/CleverCode
*/
class User
{/*{{{*/
public $id;
public $name;
public function __construct($id,$name)
{
$this->id = $id;
$this->name = $name;
}
public function setId($id)
{
$this->id = $id;
}
public function getId()
{
return $this->id;
}
public function setName($name)
{
$this->name = $name;
}
public function getName()
{
return $this->name;
}
}/*}}}*/
//操作User表
class SqlServerUser
{/*{{{*/
public function insert(User $user)
{
echo "SqlServer 向用户表插入一天记录。id:{$user->id},name:{$user->name}\r\n";
}
public function getUser($id)
{
echo "SqlServer 获取用户id:{$id}记录\r\n";
}
}/*}}}*/
class AccessUser
{/*{{{*/
public function insert(User $user)
{
echo " Access 向数据库用户表插入一天记录。id:{$user->id},name:{$user->name}\r\n";
}
public function getUser($id)
{
echo " Access 获取用户id:{$id}记录\r\n";
}
}/*}}}*/
//部门表
class Dept
{/*{{{*/
public $id;
public $name;
public function __construct($id,$name)
{
$this->id = $id;
$this->name = $name;
}
public function setId($id)
{
$this->id = $id;
}
public function getId()
{
return $this->id;
}
public function setName($name)
{
$this->name = $name;
}
public function getName()
{
return $this->name;
}
}/*}}}*/
class SqlServerDept
{/*{{{*/
public function insert(Dept $dept)
{
echo "SqlServer 部门插入一天记录。id:{$dept->id},name:{$user->dept}\r\n";
}
public function getUser($id)
{
echo "SqlServer 获取部门id:{$id}记录\r\n";
}
}/*}}}*/
class AccessDept
{/*{{{*/
public function insert(Dept $dept)
{
echo " Access 部门表表插入一天记录。id:{$user->id},name:{$user->name}\r\n";
}
public function getUser($id)
{
echo " Access 获取部门id:{$id}记录\r\n";
}
}/*}}}*/
//抽象工厂(简单工厂+反射进行改进)
class DataOperate
{/*{{{*/
public $db;
public function __construct()
{
$this->setDB($this->getDbConfig());
}
public function setDB($db)
{
$this->db = $db;
}
//读取配置文件(使用配置文件配合反射)
public function getDbConfig()
{
//读取配置
//.....
return 'Access';
}
function createTable($table)
{
//反射[db.table]
$class = $this->db.$table;
if(class_exists($class))
{
return new $class();
}
throw new Exception($class."类没有找到!");
}
}/*}}}*/
class Client
{/*{{{*/
public static function main($argv)
{
//插入一个新的用户
$user = new User(1,'张三');
$dataOperate = new DataOperate();
$userDb = $dataOperate->createTable('User');
$userDb->insert($user);
}
}/*}}}*/
Client::main($argv);
?>
技术交流
CleverCode是一名架构师,技术交流,咨询问题,请加CleverCode创建的qq群(架构师俱乐部):517133582。加群和腾讯,阿里,百度,新浪等公司的架构师交流。【架构师俱乐部】宗旨:帮助你成长为架构师!