《大话设计模式》- 简单工厂模式


《大话设计模式》- 简单工厂模式

两个数的和运算,如何实现?

我们可从四个方面进行考虑:可扩展,易复用,易维护,灵活性强 . 面向对象有三大基本特征:封装、继承、多态。

工厂在现实生活中负责生产产品,在设计模式中,工厂可以理解为生产对象的一个类。

上述运算和的实现,可将每个“运算符”单独封装成独立类,再封装单独的类进行运算符类的实例化,这个创造实例的单独的类就是“工厂”,这个过程称之为“简单工厂模式”。


优点:

1. 将创建实例的工作和使用实例的工作隔离,使用者无需关心对象是如何创建的,实现解耦

2. 将初始化实例的过程放到“工厂”里面执行,更易维护

缺点:

1. 对象初始化的工作集中在“工厂”中完成,如果“工厂”罢工,整个系统都将陷入瘫痪。

2. 对象不断的增加,势必要修改“工厂”类的逻辑来适应,会导致“工厂”逻辑越来越臃肿、复杂 ( 如上述的问题,出现1000种运算符的情况,是不是就需要出现 1000 个 case 分支进行判断运算符 ? )

3. “简单工厂模式”又称为“静态工厂方法模式”,即使用了静态方法,而静态方法无法被继承、重写,所以会造成工厂角色无法形成基于继承的等级结构。


看一个简单的 PHP 示例

<code>// 自动加载 - 测试用
// 后面引用的 autoload 全部为该文件
spl_autoload_register(function($class) {
$prefix = 'Mode\\\\';
$dir = __DIR__.'\\\\';
$len = strlen($prefix);
if(strncmp($prefix, $class, $len) !== 0){
return ;
}
$relative = strtolower(substr($class, $len));
$paths = explode('\\\\', $relative);
$name = $paths[sizeof($paths) - 1];
$file = $dir.str_replace($name, ucfirst($name), $relative).'.php';
if(file_exists($file)){
require $file;
}
});/<code>
<code>// 工厂类
namespace Mode\\Factory\\Simple;
class OperationFactory {
protected $operator;
public function __construct($operator = '+') {

$this->operator = $operator;
}
public function createOperation() {
$operation = null;
switch($this->operator){
case '+':
$operation = new OperationAdd();
break;
case '-':
$operation = new OperationSub();
break;
case '*':
$operation = new OperationMul();
break;
case '/':
$operation = new OperationDiv();
break;
}
return $operation;
}
}/<code>
<code>// 运算类
namespace Mode\\Factory\\Simple;
abstract class Operation {
protected $numA = 0;
protected $numB = 0;
abstract public function getResult();
public function setNumbers($numA = 0, $numB = 0) {
$this->numA = $numA;
$this->numB = $numB;
}
}/<code>
<code>// 加
namespace Mode\\Factory\\Simple;
class OperationSub extends Operation {
public function getResult() {
// TODO: Implement getResult() method.
return $this->numA - $this->numB;
}
}/<code>
<code>// 减
namespace Mode\\Factory\\Simple;
class OperationSub extends Operation {
public function getResult() {
// TODO: Implement getResult() method.
return $this->numA - $this->numB;
}

}/<code>
<code>// 乘
namespace Mode\\Factory\\Simple;
class OperationMul extends Operation {
public function getResult() {
// TODO: Implement getResult() method.
return $this->numA * $this->numB;
}
}/<code>
<code>// 除
namespace Mode\\Factory\\Simple;
class OperationDiv extends Operation {
public function getResult() {
// TODO: Implement getResult() method.
return $this->numA / $this->numB;
}
}

// ..../<code>
<code>// 调用
require '../../autoload.php';
use Mode\\Factory\\Simple\\OperationFactory;
$operator = '/';
$numA = 10;
$numB = 20;
$factory = new OperationFactory($operator);
$operate = $factory->createOperation();
$operate->setNumbers($numA, $numB);
echo $numA.$operator.$numB.'='.round($operate->getResult(), 2);/<code>


分享到:


相關文章: