工廠模式是什么?是不是在工廠做事呢?我相信有一些朋友對于php工廠模式還是有一些不理解,下文整理一些關于工廠模式例子.
簡單工廠模式:
①抽象基類:類中定義抽象一些方法,用以在子類中實現
②繼承自抽象基類的子類:實現基類中的抽象方法
③工廠類:用以實例化對象
php面向對象之工廠模式示例,先看一種代碼:
- <?php
- class Calc{
- /**
- * 計算結果
- *
- * @param int|float $num1
- * @param int|float $num2
- * @param string $operator
- * @return int|float
- */
- public function calculate($num1,$num2,$operator){
- try {
- $result=0;
- switch ($operator){
- case '+':
- $result= $num1+$num2;
- break;
- case '-':
- $result= $num1-$num2;
- break;
- case '*':
- $result= $num1*$num2;
- break;
- case '/':
- if ($num2==0) {
- throw new Exception("除數不能為0");
- }
- $result= $num1/$num2;
- break;
- }
- return $result;
- }catch (Exception $e){
- echo "您輸入有誤:".$e->getMessage();
- }
- }
- }
- $test=new Calc();
- // echo $test->calculate(2,3,'+');//打印:5
- echo $test->calculate(5,0,'/');//打印:您輸入有誤:除數不能為0
- ?>
優點:以上代碼使用了面向對象的封裝特性,只要有了include這個類,其他頁面就可以隨便使用了.
缺點:無法靈活的擴展和維護
比如:想要增加一個“求余”運算,需要在switch語句塊中添加一個分支語句,代碼需要再加一個case進行判斷,于是產生了以下問題.
①需要改動原有的代碼塊,可能會在為了“添加新功能”而改動原有代碼的時候,不小心將原有的代碼改錯了.
②如果要添加的功能很多,比如:‘乘方’,‘開方’,‘對數’,‘三角函數’,‘統計’,或者添加一些程序員專用的計算功能,比如:And, Or, Not, Xor,這樣就需要在switch語句中添加N個分支語句,想象下,一個計算功能的函數如果有二三十個case分支語句,代碼將超過一屏,不僅令代碼的可讀性大大降低,關鍵是,為了添加小功能,還得讓其余不相關都參與解釋,這令程序的執行效率大大降低.
解決途徑:采用OOP的繼承和多態思想.
- <?php
- /**
- * 操作類
- * 因為包含有抽象方法,所以類必須聲明為抽象類
- */
- abstract class Operation{
- //抽象方法不能包含函數體
- abstract public function getValue($num1,$num2);//強烈要求子類必須實現該功能函數
- }
- /**
- * 加法類
- */
- class OperationAdd extends Operation {
- public function getValue($num1,$num2){
- return $num1+$num2;
- }
- }
- /**
- * 減法類
- */
- class OperationSub extends Operation {
- public function getValue($num1,$num2){
- return $num1-$num2;
- }
- }
- /**
- * 乘法類
- */
- class OperationMul extends Operation {
- public function getValue($num1,$num2){
- return $num1*$num2;
- }
- }
- /**
- * 除法類
- */
- class OperationDiv extends Operation {
- public function getValue($num1,$num2){
- try {
- if ($num2==0){
- throw new Exception("除數不能為0");
- }else {
- return $num1/$num2;
- }
- }catch (Exception $e){
- echo "錯誤信息:".$e->getMessage();
- }
- }
- }
- ?>
- <?php
- /**
- * 操作類
- * 因為包含有抽象方法,所以類必須聲明為抽象類
- */
- abstract class Operation{
- //抽象方法不能包含函數體
- abstract public function getValue($num1,$num2);//強烈要求子類必須實現該功能函數
- }
- /**
- * 加法類
- */
- class OperationAdd extends Operation {
- public function getValue($num1,$num2){
- return $num1+$num2;
- }
- }
- /**
- * 減法類
- */
- class OperationSub extends Operation {
- public function getValue($num1,$num2){
- return $num1-$num2;
- }
- }
- /**
- * 乘法類
- */
- class OperationMul extends Operation {
- public function getValue($num1,$num2){
- return $num1*$num2;
- }
- }
- /**
- * 除法類
- */
- class OperationDiv extends Operation {
- public function getValue($num1,$num2){
- try { //開源軟件:Vevb.com
- if ($num2==0){
- throw new Exception("除數不能為0");
- }else {
- return $num1/$num2;
- }
- }catch (Exception $e){
- echo "錯誤信息:".$e->getMessage();
- }
- }
- }
- ?>
這里采用了面向對象的繼承特性,首先聲明一個虛擬基類,在基類中指定子類務必實現的方法(getValue()).
分析:通過采用面向對象的繼承特性,我們可以很容易就能對原有程序進行擴展,比如:‘乘方’,‘開方’,‘對數’,‘三角函數’,‘統計’等等.
我們只需要另外寫一個類(該類繼承虛擬基類),在類中完成相應的功能(比如:求乘方的運算),而且大大的降低了耦合度,方便日后的維護及擴展.
現在還有一個問題未解決,就是如何讓程序根據用戶輸入的操作符實例化相應的對象呢?
解決辦法:使用一個單獨的類來實現實例化的過程,這個類就是工廠.
- <?php
- /**
- * 工程類,主要用來創建對象
- * 功能:根據輸入的運算符號,工廠就能實例化出合適的對象
- *
- */
- class Factory{
- public static function createObj($operate){
- switch ($operate){
- case '+':
- return new OperationAdd();
- break;
- case '-':
- return new OperationSub();
- break;
- case '*':
- return new OperationSub();
- break;
- case '/':
- return new OperationDiv();
- break;
- }
- }
- }
- $test=Factory::createObj('/');
- $result=$test->getValue(23,0);
- echo $result;
- ?>
我對些的總結就是:根據傳遞的參數(對象)不同,調用不同的工廠(類),然后用以實現指定的功能,比較大的好處就是簡化了以前函數化編程的switch case,if else之類,進行類的分發,不同的東西調用不同的類.
新聞熱點
疑難解答