由于简单工厂模式违反了设计模式六大原则中的“开闭原则”,所以产生了工厂模式,工厂模式定义一个创建对象的接口,让子类决定实例化那一个类。工厂方法使一个类的实例化延迟到子类。以之前的简单工厂模式所实现的功能为例,工厂模式的代码如下。
工厂接口
<?php
include './Claculator.php';
include './claculator/Add.php';
include './claculator/Divide.php';
include './claculator/Tract.php';
include './claculator/Ride.php';
interface Factory
{
static function createClaculator();
}
加法工厂
<?php
class AddFactory implements Factory
{
public static function createClaculator()
{
return new Add();
}
}
减法工厂
<?php
class TractFactory implements Factory
{
public static function createClaculator()
{
return new Tract();
}
}
乘法工厂
<?php
class RideFactory implements Factory
{
public static function createClaculator()
{
return new Ride();
}
}
除法工厂
<?php
class DivideFactory implements Factory
{
public static function createClaculator()
{
return new Divide();
}
}
计算接口
<?php
Interface Claculator
{
function evaluate($numberA, $numberB);
}
加法计算类
<?php
class Add implements Claculator
{
public function evaluate($numberA, $numberB)
{
return $numberA+$numberB;
}
}
减法计算类
<?php
class Tract implements Claculator
{
public function evaluate($numberA, $numberB)
{
return $numberA-$numberB;
}
}
乘法计算类
<?php
class Ride implements Claculator
{
public function evaluate($numberA, $numberB)
{
return $numberA*$numberB;
}
}
除法计算类
<?php
class Divide implements Claculator
{
public function evaluate($numberA, $numberB)
{
if ($numberB==0)
return null;
return $numberA/$numberB;
}
}
客户端代码
<?php
$numberA = isset($_GET['a'])?$_GET['a']:0;
$numberB = isset($_GET['b'])?$_GET['b']:0;
$type = isset($_GET['type'])?$_GET['type']:'+';
include './Factory.php';
include './factory/DivideFactory.php';
include './factory/AddFactory.php';
include './factory/TractFactory.php';
include './factory/RideFactory.php';
switch ($type) {
case '+':
$server = AddFactory::createClaculator();
break;
case '-':
$server = TractFactory::createClaculator();
break;
case '*':
$server = RideFactory::createClaculator();
break;
case '/':
$server = DivideFactory::createClaculator();
break;
case '':
$server = null;
break;
}
if (empty($server))
$result = 0;
else
$result = $server->evaluate($numberA, $numberB);
var_dump($result);
UML类图
UML类图类似于这个图,这是从《大话设计模式》中截取的图片,只不过是类名称需要变化一下,体现的内容大同小异。
简单工厂模式VS工厂模式
工厂模式克服了简单工厂模式中违反了“开闭原则”的缺点,又保持了封装对象创建过程的优点。但工厂模式仅仅只为创建一个对象,就生成了2倍的类文件,个人感觉有点浪费。
简单工厂模式最大的优点在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态选择实例化的类,对于客户端来说,去除了与具体产品的依赖,符合“迪米特原则”。
下一篇
初识设计模式——装饰器模式