《大話設計模式》- 簡單工廠模式


《大話設計模式》- 簡單工廠模式

兩個數的和運算,如何實現?

我們可從四個方面進行考慮:可擴展,易複用,易維護,靈活性強 . 面向對象有三大基本特徵:封裝、繼承、多態。

工廠在現實生活中負責生產產品,在設計模式中,工廠可以理解為生產對象的一個類。

上述運算和的實現,可將每個“運算符”單獨封裝成獨立類,再封裝單獨的類進行運算符類的實例化,這個創造實例的單獨的類就是“工廠”,這個過程稱之為“簡單工廠模式”。


優點:

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>


分享到:


相關文章: