PHP設計模式(二)——工廠模式(Factor Pattern)
阿新 • • 發佈:2018-11-19
@[TOC](PHP設計模式(二)——工廠模式(Factor Pattern))
工廠模式(Factor Pattern),就是負責生成其他物件的類或方法
(一)為什麼需要工廠模式
- 工廠模式可以將物件的生產從直接new 一個物件,改成通過呼叫一個工廠方法生產。這樣的封裝,程式碼若需修改new的物件時,不需修改多處new語句,只需更改生產物件方法。
- 若所需例項化的物件可選擇來自不同的類,可省略if-else多層判斷,給工廠方法傳入對應的引數,利用多型性,例項化對應的類。
(二)簡單實現程式碼
// 工廠類 class Factor { static function createDb() { echo '我生產了一個例項——'; return new DB(); } } // 資料庫類 class DB { public function __construct() { echo __CLASS__.PHP_EOL; } } $db = Factor::createDb();
(三)實現一個運算器
// 抽象運算類 abstract class Operation { abstract public function getVal($i, $j); } // 繼承抽象類的 加法類 class OperationAdd extends Operation { public function getVal($i, $j) { return $i + $j; } } // 繼承抽象類的 減法類 class OperationSub extends Operation { public function getVal($i, $j) { return $i - $j; } } // 計算器工廠 class CounterFactor { private static $operation; // 工廠生產特定類物件方法 static function createOperation(string $operation) { switch ($operation) { case '+' : self::$operation = new OperationAdd(); break; case '-' : self::$operation = new OperationSub(); break; } return self::$operation; } } $counter = CounterFactor::createOperation('-'); echo $counter->getVal(1, 2);
缺點:若是再增加一個乘法運算,除了增加一個乘法運算類之外,還得去工廠生產方法裡面新增對應的case程式碼,違反了開放-封閉原則。
解決方法(1):通過傳入指定類名
abstract class Operation { abstract public function getVal($i, $j); } // 繼承抽象類的 加法類 class OperationAdd extends Operation { public function getVal($i, $j) { return $i + $j; } } // 繼承抽象類的 減法類 class OperationSub extends Operation { public function getVal($i, $j) { return $i - $j; } } // 繼承抽象類的 乘法類 class OperationMul extends Operation { public function getVal($i, $j) { return $i * $j; } } // 計算器工廠 class CounterFactor { // 工廠生產特定類物件方法 static function createOperation(string $operation) { return new $operation; } } $counter = CounterFactor::createOperation('OperationMul'); echo $counter->getVal(1, 2);
解決方法(2):通過抽象工廠模式
抽象高於實現
其實我們完全可以抽象出一個抽象工廠,然後將對應的物件生產交給子工廠實現。程式碼如下
<?php
abstract class Operation
{
abstract public function getVal($i, $j);
}
// 繼承抽象類的 加法類
class OperationAdd extends Operation
{
public function getVal($i, $j)
{
return $i + $j;
}
}
// 繼承抽象類的 減法類
class OperationSub extends Operation
{
public function getVal($i, $j)
{
return $i - $j;
}
}
// 繼承抽象類的 乘法類
class OperationMul extends Operation
{
public function getVal($i, $j)
{
return $i * $j;
}
}
// 繼承抽象類的 除法類
class OperationDiv extends Operation
{
public function getVal($i, $j)
{
return $i / $j;
}
}
// 抽象工廠類
abstract class Factor
{
abstract static function getInstance();
}
// 加法子工廠
class AddFactor extends Factor
{
// 工廠生產特定類物件方法
static function getInstance()
{
return new OperationAdd();
}
}
// 減法子工廠
class SubFactor extends Factor
{
// 工廠生產特定類物件方法
static function getInstance()
{
return new OperationSub();
}
}
// 乘法子工廠
class MulFactor extends Factor
{
// 工廠生產特定類物件方法
static function getInstance()
{
return new OperationMul();
}
}
// 除法子工廠
class DivFactor extends Factor
{
// 工廠生產特定類物件方法
static function getInstance()
{
return new OperationDiv();
}
}
echo AddFactor::getInstance()->getVal(1, 2).PHP_EOL;
echo SubFactor::getInstance()->getVal(1, 2).PHP_EOL;
echo MulFactor::getInstance()->getVal(1, 2).PHP_EOL;
echo DivFactor::getInstance()->getVal(1, 2).PHP_EOL;