設計模式是軟體工程的基石,如同大廈的一塊塊磚石一樣。專案中合理地運用設計模式可以完美地解決很多問題,每種模式在現實中都有相應的原理來與之對應,每種模式都描述了乙個在我們周圍不斷重**生的問題,以及該問題的核心解決方案,這也是設計模式能被廣泛應用的原因。
19.2 工廠模式
工廠模式屬於建立型模式,提供了一種建立物件的方式。工廠模式是先定義乙個建立物件的介面,讓其子類自己決定例項化哪乙個工廠類。使用工廠模式的擴充套件性高,如果想增加乙個產品,只要擴充套件乙個工廠類就可以了,其遮蔽了產品的具體實現,呼叫者只需關心產品的介面。工廠模式的精髓就是可以根據不同的引數生成不同的類例項。
比如我們定義乙個類來實現兩個數的加、減、乘、除,**如下:
<?php
class calc
$result=$num1/$num2;
break;
case '%':
$result=$num1%$num2;
break;
}return $result;
} catch(exception $e)
}}$test= new calc();
echo $test->calculate(2,3,'+');//列印:5
echo $test->calculate(5,0,'/');//列印:您輸入有誤:除數不能為0
echo $test->calculate(7,4,'%');//列印:3
當需要類再實現乙個可以「求餘」的運算時,便可在switch語句塊中新增乙個分支語句,**需要做如下改動:
用以上方法實現給計算器新增新的功能運算有以下幾個缺點:
(1)需要改動原有的**塊,可能會在為了「新增新功能」而改動原有**的時候不小心將原有的**改錯了。
(2)如果要新增的功能很多,比如「乘方」「開方」「對數」「三角函式」「統計」,或者新增一些程式設計師專用的計算功能,比如and、or、not、xor,這樣就需要在switch語句中新增n個分支語句。想象一下,乙個計算功能的函式如果有二三十個case分支語句,**將超過一屏,不僅令**的可讀性大大降低,關鍵是為了新增小功能得不償失,令程式的執行效率大大降低。
為了解決以上問題,我們可以採用工廠模式,思路是定義「加減乘除」4個類,這4個類中都有getvalue()方法,然後定義乙個可以建立「加減乘除」的類,稱之為工廠類,該工廠類中有乙個工廠方法,我們根據可傳入到工廠方法的不同引數(可以是「加減乘除」的數學符號)使用這個工廠類的工廠方法建立「加減乘除」類,然後呼叫其對應的getvalue() 方法獲得返回結果。
工廠模式**如下:
<?php
//定義介面
inte***ce calc
//建立實現介面的實體類
class add implements calc
}class sub implements calc
}class mul implements calc
}class div implements calcelse
}catch (exception $e)
}}//建立乙個工廠,生成基於給定資訊的實體類的物件
class factory
}}$test=factory::createobj('/');
echo $test->getvalue(1,0);
這樣我們就實現了根據使用者輸入的操作符例項化相應的物件,進而可完成接下來相應的操作。在軟體開發中,php可能要鏈結mysql,也可能鏈結sqlserver或者其他資料庫,這樣我們就可以定義乙個工廠類,動態產生不同的資料庫鏈結物件。再比如設計乙個連線伺服器的框架,需要3個協議,即pop3、imap、http,可以把這3個作為產品類,共同實現乙個介面。工廠模式的使用場景很多,需要讀者在實際開發中嘗試應用。
19.3 單例模式
單例模式涉及乙個單一的類,該類負責建立自己的物件,同時確保只有單個物件被建立。單例模式主要解決乙個全域性使用的類被頻繁建立與銷毀的問題,由於只建立了乙個類的例項,因此減少了記憶體開銷、節省了系統資源。php中單例模式經常被用在資料庫應用中。
<?php
/* * 設計模式的單便模式
* $_instance必須宣告為靜態的私有變數
* 建構函式必須宣告為私有,防止外部程式new類從而失去單便模式的意義
* getinstance()方法必須設定為公有的,必須呼叫此方法以返回例項的乙個引用
* ::操作符只能訪問靜態變數和靜態函式
* new物件都會消耗記憶體
* 使用單便模式生成乙個物件後,該物件可以被其他眾多物件所使用
* */
class man
//單例方法
public static function get_instance()
return self::$_instance;
}//阻止使用者複製物件例項
private function __clone()
function test()
}//這個寫法會出錯,因為構造方法被宣告為private
//$test = new man();
//下面將得到example類的單例物件
$test = man::get_instance();
$test = man::get_instance();
$test->test();
//複製物件將導致乙個e_user_error
//$test_clone = clone $test;
執行以上程式的輸出結果為:
我被例項化了!test
19.4 觀察者模式
19.5 策略模式
在策略模式(strategy pattern)中,乙個類的行為或演算法可以在執行時更改。這種型別的設計模式屬於行為型模式。其實現原理是定義一系列的演算法,將它們乙個個封裝起來,並且可以互相替換,這樣避免了使用if … else語句所帶來的複雜度和維護成本。如果乙個系統裡有許多的類,而這些類之間的區別僅在於它們行為的不同,系統也需要動態地選擇幾種演算法中的一種,這時使用策略模式是一種很好的解決方案。
下面的示例演示兩個數之間的「加減乘除」運算。在工廠模式中,我們使用工廠模式實現了這種計算,根據傳入的引數而分別生成不同的類例項。這裡的示例使用策略模式來實現這種數**算,**如下:
<?php
//定義介面
inte***ce calc
//建立實現介面的實體類
class addstrategy implements calc
}class substrategy implements calc
}class mulstrategy implements calc
}class divstrategy implements calcelse
}catch (exception $e)
}}//calc策略類,傳入的引數(具體行為的類)
class calccontext
//設定使用的策略類方法
public function setcalc(calc $select)
//獲取計算結果方法
public function calcresult($m,$n)
}$result=new calccontext(new addstrategy());
echo $result->calcresult(10,2);
echo " ";
//切換不同策略
$result->setcalc(new divstrategy());
$result->calcresult(10,2);
執行以上程式,在瀏覽器中的輸出結果為:
12 5
我們使用策略模式和工廠模式都可以實現這種功能,區別是:工廠模式關注物件的建立、提供建立物件的介面,是建立型的設計模式,接受指令,建立出符合要求的例項;策略模式是行為型的設計模式,接受已經建立好的例項,實現不同的行為。
php7實踐指南 ch13目錄檔案檔案指標
php可以實現檔案指標的定位及查詢,從而實現所需資訊的快速查詢。指標的位置就是從檔案頭部開始的位元組數,預設的檔案指標通常存在於檔案頭或結尾,可以通過php提供的fseek feof 和ftell 等函式對指標位置進行操作。rewind 倒回檔案指標的位置,語法如下 function rewind ...
php7實踐指南 ch13目錄檔案檔案上傳
在開發中經常需要通過php向伺服器上傳一些檔案,比如使用者頭像 商品等。13.4.1 上傳檔案配置 上傳檔案時需要配置php.ini中的幾個引數,如表13 2所示。假設要上傳乙個50mb的大檔案,配置php.ini檔案 注意,需要保持memory limit post max size upload...
php7實踐指南 ch9類與方法 自動載入
9.4 自動載入 很多時候寫物件導向的應用程式時對每個類的定義建立乙個php原始檔。乙個很大的煩惱是不得不在每個指令碼開頭寫乙個長長的包含檔案列表 每個類乙個檔案 對於每乙個類檔案都需要使用require或者include引入。php中提供了兩個可用來自動載入檔案的函式 autoload 和spl ...