三种工厂模式对比
例子来自<大话设计模式>一书,php代码由个人实现
简单工厂模式:
一个抽象产品类(可以是:接口,抽象类,普通类),可以派生出多个具体产品类。
单独一个具体的工厂类。
每个具体工厂类只能创建一个具体产品类的实例。
工厂方法模式:
一个抽象产品类(可以是:接口,抽象类,普通类),可以派生出多个具体产品类。
一个抽象工厂类(可以是:接口,抽象类),可以派生出多个具体工厂类。
每个具体工厂类只能创建一个具体产品类的实例。
抽象工厂模式:
多个抽象产品类(可以是:接口,抽象类,普通类),每个抽象产品类可以派生出多个具体产品类。
一个抽象工厂类(可以是:接口,抽象类),可以派生出多个具体工厂类。
每个具体工厂类可以创建多个具体产品类的实例。
区别:
简单工厂模式只有一个抽象产品类,只有一个具体的工厂类。
工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个抽象产品类。
工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个具体产品类的实例。
简单工厂模式
UML类图如下:

当需要加法类的时候,调用工厂类的CreateOperate(),要指定制造的Product
调用工厂,需要createOperator("/"),就能返回除法运算符。
优点:客户端不需要修改代码。
缺点: 当需要增加新的运算类的时候,不仅需新加运算类,还要修改工厂类,违反了开闭原则。
简单工厂模式程序设计图:

具体实现:
1)抽象产品(Product)角色:运算抽象类(Operation)。
// 运算抽象类
class Operation{
// 数字A
protected $_numberA = null;
// 数字B
protected $_numberB = null;
/**
* 设置成员A
*
* @param double $num 数字
* @return void
*/
public function setNumberA($num){
$this->_numberA = $num;
}
/**
* 获取成员A
*
* @return double 数字
*/
public function getNumberA(){
return $this->_numberA;
}
/**
* 设置成员B
*
* @param double $num 数字
* @return void
*/
public function setNumberB($num){
$this->_numberB = $num;
}
/**
* 获取成员B
*
* @return double 数字
*/
public function getNumberB(){
return $this->_numberA;
}
/**
* 获取运算结果
*
* @return double 数字
*/
public function getResult(){
return null;
}
}
2)具体产品(Concrete Product)角色:加法运算(OperationAdd),减法运算(OperationSub),乘法运算(OperationMul),除法运算(OperationDiv)。
// 加法类
class OperationAdd extends Operation{
/**
* 获取运算结果
*
* @return double 数字
*/
public function getResult(){
return $this->_numberA + $this->_numberB;
}
}
// 减法类
class OperationSub extends Operation{
/**
* 获取运算结果
*
* @return double 数字
*/
public function getResult(){
return $this->_numberA - $this->_numberB;
}
}
// 乘法类
class OperationMul extends Operation{
/**
* 获取运算结果
*
* @return double 数字
*/
public function getResult(){
return $this->_numberA * $this->_numberB;
}
}
// 除法类
class OperationDiv extends Operation{
/**
* 获取运算结果
*
* @return double 数字
*/
public function getResult(){
if ($this->_numberB == 0) {
return null;
}
return $this->_numberA / $this->_numberB;
}
}
3)工厂(Creator)角色:工厂类(OperationFactory)。
/**
*
* 设计模式:简单工厂模式
*
* 模式简介:用一个单独的类来创造实例化的过程,叫做简单工厂。好处将来增加或减少
* 实例只需要修改工厂即可。
*
*/
// 创建一个工程,用来生产实例
class OperationFactory{
/**
* 根据运算不同实例不同的对象
*
* @return object 返回实例化的对象
*/
public static function createOperate($operate){
$oper = null;
switch ($operate) {
// 实例加法类
case '+' :
$oper = new OperationAdd();
break;
// 实例减法类
case '-' :
$oper = new OperationSub();
break;
// 实例乘法类
case '*' :
$oper = new OperationMul();
break;
// 实例乘法类
case '/' :
$oper = new OperationDiv();
break;
default :
$oper = null;
}
return $oper;
}
}
/*
* 客户端
*
*/
// 工厂创建实例
$operObject = OperationFactory::createOperate('+');
if ($operObject == null) {
return '$operate not found';
}
// 设置数字A
$operObject->setNumberA(5);
// 设置数字B
$operObject->setNumberB(2);
// 运算
echo $operObject->getResult() . "\n";
工厂方法模式
UML类图如下:

这个和简单工厂有区别,简单工厂模式只有一个工厂,工厂方法模式对每一个产品都有相应的工厂
好处:增加一个运算类(例如N次方类),只需要增加运算类和相对应的工厂,两个类,不需要修改工厂类。
缺点:增加运算类,会修改客户端代码,工厂方法只是把简单工厂的内部逻辑判断移到了客户端进行。
改造简单工厂代码中的工厂(Creator)角色
,代码如下:
interface IFactory
{
public function CreateOperation();
}
class AddFactory implements IFactory
{
public function CreateOperation()
{
return new OperationAdd();
}
}
class SubFactory implements IFactory
{
public function CreateOperation()
{
return new OperationSub();
}
}
class MulFactory implements IFactory
{
public function CreateOperation()
{
return new OperationMul();
}
}
class DivFactory implements IFactory
{
public function CreateOperation()
{
return new OperationDiv();
}
}
/*
* 客户端代码
*
* */
// 工厂创建实例
$operationFactory = new AddFactory();
$operation = $operationFactory->CreateOperation();
// 设置数字A
$operation->setNumberA(10);
// 设置数字B
$operation->setNumberB(10);
// 运算
echo $operation->getResult() . "\n";
抽象工厂模式:
UML类图如下:
Last updated
Was this helpful?