PHP模式設計之單例模式、工廠模式、註冊樹模式、適配器模式、觀察者模式
php模式設計之單例模式
什麽是單例模式?
單例模式是指在整個應用中只有一個實例對象的設計模式
為什麽要用單例模式?
php經常要鏈接數據庫,如果在一個項目中頻繁建立連接數據庫,會造成服務器資源的很大浪費,在團隊合作項目中,也能夠避免不同的程序員實例自己的對象,造成人為的系統消耗。
單例模式的三大原則
1.構造函數需要標記為非public(防止外部使用new操作符創建對象),單例類不能在其他類中實例化,只能被其自身實例化
2.擁有一個保存類的實例的靜態成員變量$_instance
3.擁有一個可以訪問這個實例的公共靜態方法
示例代碼
<?php/** * php設計模式之單例模式 */ class Db { static private $_instance; final protected function __construct() { # code... } public static function getInstance() { if (!self::$_instance instanceof self) { self::$_instance=new Db(); } return self::$_instance; } public function connect() { //鏈接數據庫 } } ?>
php模式設計之工廠模式
什麽是工廠模式?
工廠模式是指根據不同的參數生成不同的類實例。
為什麽要用工廠模式?
減少代碼進行復制粘帖,耦合關系重,牽一發動其他部分代碼,比如在項目中很多地方實例化某個類,現在突然發現類名不合適或者類中需要添加構造函數參數,難不成需要一個個改?典型的例子就是連接數據庫,php中連接數據庫有好幾種方法,mysql擴展,mysqli擴展等,這個時候就可以用到工廠模式。
示例代碼
<?php /** * php設計模式之工廠模式 */ class Db { public static function factory($param){ switch ($param) { case ‘mysql‘: return new Class1(); break; case ‘mysqli‘: return new Class2(); break; case ‘mssql‘: return new Class3(); break; } } } interface Connect { public function fun1($param); } class Class1 implements Connect { public function fun1($param){ //具體實現 } } class Class2 implements Connect { public function fun1($param){ //具體實現 } } class Class3 implements Connect { public function fun1($param){ //具體實現 } } ?>
php模式設計之註冊樹模式
什麽是註冊樹模式?
註冊樹模式通過將對象實例註冊到全局對象樹上,需要的時候將對象從全局對象樹上取下來
為什麽要用工廠模式?
前面講到的單例模式解決了在整個項目中創建唯一對象的問題,工廠模式解決了不通過new解決實例對象的問題,考慮的是項目擴展與維護。總得來說單例模式和工廠模式可以產生更加合理的對象,那麽怎麽方便統籌調用這些對象呢,這時候就用到了註冊樹模式,不管你是單例模式,工廠模式還是二者結合生成的對象,都統統給我註冊到樹上,用某個對象的時候,直接從樹上取下來就好。
示例代碼
<?php /** * 單例模式 */ class Signal { static private $_instance; final protected function __construct() { # code... } public static function getInstance() { if (!self::$_instance instanceof self) { self::$_instance=new Signal(); } return self::$_instance; } public function connect() { //鏈接數據庫 } } /** * 工廠模式 */ class Db { public static function factory($param=‘‘) { switch ($param) { case ‘mysql‘: return new Class1(); break; case ‘mysqli‘: return new Class2(); break; case ‘mssql‘: return new Class3(); break; default: return Signal::getInstance(); } } } interface Connect { public function fun1($param); } class Class1 implements Connect { public function fun1($param) { //具體實現 } } class Class2 implements Connect { public function fun1($param) { //具體實現 } } class Class3 implements Connect { public function fun1($param) { //具體實現 } } /** *註冊樹模式 */ class Register { static protected $objects; /** * 插入對象實例 * @param string $alias * @param object $object 對象實例 */ public static function set($alias,$object) { self::$objects[$alias]=$object; } /** * 撤銷對象實例 * @param string $alias */ public static function _unset($alias) { unset(self::$objects[$alias]); } /** * 獲取對象實例 * @param string $alias * return object */ public static function get($alias) { return self::$objects[$alias]; } } Register::set(‘signal‘,Db::factory()); $signal=Register::get(‘signal‘); $signal->connect(); ?>
php模式設計之適配器模式
什麽是適配器模式?
把對某些相似的類的操作轉化為一個統一的"接口"--適配器,或者比喻為某個"界面",統一或者屏幕那些類的細節.適配器模式還構造了一種"機制",使"適配"的類很容易增減,而不用修改與之交互的代碼,符合減少代碼間的耦合。
為什麽要用適配器模式?
主要應用於"希望復用一些現成的類,但是接口又與復用環境不一致"的情況
示例代碼
1.源(Adaptee)角色:Toy系列類保持不變
<?php abstract class Toy { public abstract function openMouth(); public abstract function closeMouth(); } class Dog extends Toy { public function openMouth() { echo "Dog open Mouth\n"; } public function closeMouth() { echo "Dog close Mouth\n"; } } class Cat extends Toy { public function openMouth() { echo "Cat open Mouth\n"; } public function closeMouth() { echo "Cat close Mouth\n"; } } ?>
2.目標(Target)角色接口
<?php //目標角色:紅棗遙控公司 interface RedTarget { public function doMouthOpen(); public function doMouthClose(); } //目標角色:綠棗遙控公司及 interface GreenTarget { public function operateMouth($type = 0); } ?>
3.適配器角色代碼實現
//類適配器角色:紅棗遙控公司 class RedAdapter implements RedTarget { private $adaptee; function __construct(Toy $adaptee) { $this->adaptee = $adaptee; } //委派調用Adaptee的sampleMethod1方法 public function doMouthOpen() { $this->adaptee->openMouth(); } public function doMouthClose() { $this->adaptee->closeMouth(); } } //類適配器角色:綠棗遙控公司 class GreenAdapter implements GreenTarget { private $adaptee; function __construct(Toy $adaptee) { $this->adaptee = $adaptee; } //委派調用Adaptee:GreenTarget的operateMouth方法 public function operateMouth($type = 0) { if ($type) { $this->adaptee->openMouth(); } else { $this->adaptee->closeMouth(); } } }
4.測試用例
<?php class testDriver { public function run() { //實例化一只狗玩具 $adaptee_dog = new Dog(); echo "給狗套上紅棗適配器\n"; $adapter_red = new RedAdapter($adaptee_dog); //張嘴 $adapter_red->doMouthOpen(); //閉嘴 $adapter_red->doMouthClose(); echo "給狗套上綠棗適配器\n"; $adapter_green = new GreenAdapter($adaptee_dog); //張嘴 $adapter_green->operateMouth(1); //閉嘴 $adapter_green->operateMouth(0); } } $test = new testDriver(); $test->run(); ?>
php模式設計之觀察者模式
什麽是觀察者模式?
從面向過程的角度來看,首先是觀察者向主題註冊,註冊完之後,主題再通知觀察者做出相應的操作,整個事情就完了
從面向對象的角度來看,主題提供註冊和通知的接口,觀察者提供自身操作的接口。(這些觀察者擁有一個同一個接口。)觀察者利用主題的接口向主題註冊,而主題利用觀察者接口通知觀察者。耦合度相當之低
為什麽要用觀察者模式?
觀察者模式更多體現了兩個獨立的類利用接口完成一件本應該很復雜的事情。不利用主題類的話,我們還需要不斷循環創建實例,執行操作。而現在只需要創建實例就好,執行操作的事兒只需要調用一次通知的方法就好啦
示例代碼
<?php // 主題接口 interface Subject{ public function register(Observer $observer); public function notify(); } // 觀察者接口 interface Observer{ public function watch(); } // 主題 class Action implements Subject{ public $_observers=array(); public function register(Observer $observer){ $this->_observers[]=$observer; } public function notify(){ foreach ($this->_observers as $observer) { $observer->watch(); } } } // 觀察者 class Cat implements Observer{ public function watch(){ echo "Cat watches TV<hr/>"; } } class Dog implements Observer{ public function watch(){ echo "Dog watches TV<hr/>"; } } class People implements Observer{ public function watch(){ echo "People watches TV<hr/>"; } } // 應用實例 $action=new Action(); $action->register(new Cat()); $action->register(new People()); $action->register(new Dog()); $action->notify(); ?>
PHP模式設計之單例模式、工廠模式、註冊樹模式、適配器模式、觀察者模式