久久久久久久av_日韩在线中文_看一级毛片视频_日本精品二区_成人深夜福利视频_武道仙尊动漫在线观看

自制PHP框架之設(shè)計模式

本文是自制PHP框架的第三篇,我們主要來講解下PHP的設(shè)計模式的使用,本文我們一起來學(xué)習(xí)PHP中最常用的三種設(shè)計模式:單例設(shè)計模式、工廠設(shè)計模式和觀察者設(shè)計模式。

為什么要使用設(shè)計模式?

設(shè)計模式,我的理解是為了達(dá)到“可復(fù)用”這個目標(biāo),而設(shè)計的一套相互協(xié)作的類。

感興趣的讀者可以閱讀《Design Patterns: Elements of Reusable Object-Oriented Software》,四位作者(Gang of Four)在書中列舉了業(yè)界聞名的23種設(shè)計模式。

這里先介紹我們框架要涉及的三種設(shè)計模式。

單例模式(singleton)

單例模式可以保證一個類只有一個對象實例, 常用在數(shù)據(jù)庫存取類,從而節(jié)省硬件資源的消耗。

這里,我們改寫上一章節(jié)的MySQL類

class MySQL extends DB{
	private static $instance=null;
	public static function getInstance(){
		if(self::$instance==null){
			self::$instance=new MySQL();
		}
		return self::$instance;
	}
	public function MySQL(){
		
		/*Config*/
		$this->IP='*';
		$this->ServerID='*';
		$this->ServerPassword='*';
		$this->DataBaseName='*';
		/*End of Config*/
		
		$this->connection=mysqli_connect($this->IP,$this->ServerID,$this->ServerPassword,$this->DataBaseName);
		
		if(!$this->connection){
			die('Could not connect'.$this->connection);
		}
		
		mysqli_query($this->connection,'set names utf8');
	}

	public function Execute($sql){
		return mysqli_query($this->connection,$sql);	
	}

	public function Query($sql){
		$result=mysqli_query($this->connection,$sql);
		$arr=array();
		while($row=mysqli_fetch_array($result)){
			$arr[]=$row;
		}
		return $arr;
	}
	public function Close(){
		mysqli_close($this->connection);
	}
}

這里要注意的是,如果實例化一個MySQL類,我們不再寫

$db=new MySQL();

而是這樣:

$db=MySQL::getInstance();

因為只有g(shù)etInstance這個靜態(tài)函數(shù),才能保證只調(diào)用一次MySQL類的構(gòu)造函數(shù)。

單例模式是很常用的設(shè)計模式,這里不再贅述。

外觀模式(Facade)

因為命名空間的問題,外觀模式可以保證一個類的諸多方法看似是“一個類提供的”,這里我們先設(shè)計一個簡單的服務(wù)提供者類

class ServiceProvider{
	public function Write($arg){
		echo $arg;
	}
}

這個類只有一個Write方法,就是把參數(shù)打印出來

然后定義一個Facade類

class Facade{
	public static function getInstance($classname,$args){
		return new $classname($args);
	}
	
	public static function getFacadeAccessor(){
		//
	}
	
	public static function __callstatic($method,$args){
		$instance=static::getInstance(static::getFacadeAccessor(),$args);
		return call_user_func_array(array($instance,$method),$args);
	}
}

要理解這個類,我們只要關(guān)注最后一個函數(shù),就是__callstatic魔術(shù)方法。這個方法就是Facade類型對象或者其子類在調(diào)用他自身沒有定義過的函數(shù)時,就會調(diào)用__callstatic方法,而這個方法最后調(diào)用了call_user_func_array函數(shù),就是把任務(wù)交給提供這項服務(wù)的類去完成,同時完成參數(shù)的傳遞。

我們再寫一個Facade子類

class MyFacade extends Facade{
	public static function getFacadeAccessor(){
		return ServiceProvider::class;
	}
}

這里注意,子類實現(xiàn)了父類沒有具體實現(xiàn)的getFacadeAccessor方法,這個方法就是要告訴父類的__callstatic方法:“我作為Facade,代表的是什么哪個類,任務(wù)就由他來實現(xiàn)吧”,從語法上看,只是返回了一個表示類名的字符串。所以父類起初并不知道它的子類都代表著什么“服務(wù)提供者類”,只有當(dāng)子類的靜態(tài)函數(shù)被調(diào)用后,因為子類沒有該靜態(tài)函數(shù),所以父類的__callstatic方法被啟動了。

抽象工廠(Factory)

我對抽象工廠有一個粗俗的理解:“對象與字符串的對應(yīng)”,也就是用一個字符串就可以創(chuàng)造一個類的對象。這種做法主要用在兩種情況下是很方便的:

1.類名不穩(wěn)定,會在項目中頻繁修改

類名修改,很多時候并不是設(shè)計者的“命名潔癖”或者“命名強(qiáng)迫癥”導(dǎo)致的修改,而是在項目的不斷迭代,發(fā)覺這個類設(shè)計的不合理。如果這個類用的不頻繁,那么改個類名只要手工做一些小的修改即可,但是如果這個類通篇存在于代碼之中(假如是數(shù)據(jù)庫類),那修改工作量就大了,當(dāng)然,我們也可以對代碼文件使用“字符串替換”,但是假如一個PHP寫成的項目,PHP文件有幾十上百個,這也是不合理的事。

2.類的設(shè)計者并不是類的使用者

【網(wǎng)站聲明】本站除付費源碼經(jīng)過測試外,其他素材未做測試,不保證完整性,網(wǎng)站上部分源碼僅限學(xué)習(xí)交流,請勿用于商業(yè)用途。如損害你的權(quán)益請聯(lián)系客服QQ:2655101040 給予處理,謝謝支持。

相關(guān)文檔推薦

主站蜘蛛池模板: 久久精品99久久 | 国产视频二区 | 国产精品区二区三区日本 | 人妖一区| 亚洲精品日日夜夜 | 国产成人在线播放 | 国产乱码久久久久久 | www成人免费视频 | 午夜免费视频 | 午夜天堂精品久久久久 | 欧美精品久久久久 | 久久777| 日韩在线精品视频 | 国产欧美一区二区精品久导航 | 91免费观看国产 | 黄色毛片视频 | 影音先锋男 | 久草在线免费资源 | 理伦毛片 | 成人国产精品久久 | 精品无码三级在线观看视频 | 久久av网站| 午夜天堂精品久久久久 | 日本一区二区在线视频 | 99re视频在线观看 | 国产精品免费观看 | 国产成人一区二区 | 日韩电影在线 | 少妇午夜一级艳片欧美精品 | www亚洲精品 | 狠狠狠干| 国产精品69毛片高清亚洲 | 欧美亚州综合 | 欧美一级片 | 欧美二区三区 | 美女黄网| 亚洲视频免费在线 | 精品婷婷 | 亚洲国产一区在线 | 国产精品视频网站 | 欧美日韩精品免费 |