oop的三種設計模式(單例、工廠、策略)

參考網站php

單例模式:html

廢話很少說,咱們直接上代碼:mysql

<?php /** 三私一公 *私有的靜態屬性:保存類的單例 *私有的__construct():阻止在類的外部實例化 *私有的__clone():阻止在類的外部clone對象 *共有的靜態方法:獲取類的單例 */ class DanLi{ private static $instance; //保存類的單例 private function __construct() { //阻止在類的外部實例化 } private function __clone() { //阻止在類的外部clone對象 } //獲取當前類的單例 public static function getInstance() { if(!self::$instance instanceof self)//$instance中保存的不是MySQLDB類的單例就實例化 self::$instance=new self(); return self::$instance; //返回單例 } } //測試 $db1=DanLi::getInstance(); 
$db2=DanLi::getInstance();
var_dump($db1,$db2);
咱們能夠看到結果爲下圖:

咱們能夠看到,結果爲:兩個實例化出來對象是同樣的。這就體現了咱們單例的精髓(只能實例化出來一個實例,而且不可複製,可以節省系統資源)
注意:靜態變量上存在內存中的,它不會由於程序執行完畢二消失,因此咱們第二次實例化的時候,會檢測到instance的存在,於是直接返回已經存在的instance實例。
下面咱們來看一下單例的實際運用:用於數據庫鏈接類,由於是數據庫鏈接,咱們沒有必要每一次操做數據庫都進行一次數據庫類的實例化,那樣會大大的消耗系統資源。因此,咱們用到了單例模式,代碼以下:


//初始化鏈接參數
private function initParam($config){
$this->host=isset($config['host'])?$config['host']:'';
$this->port=isset($config['port'])?$config['port']:'3306';
$this->user=isset($config['user'])?$config['user']:'';
$this->pwd=isset($config['pwd'])?$config['pwd']:'';
$this->charset=isset($config['charset'])?$config['charset']:'utf8';
$this->dbname=isset($config['dbname'])?$config['dbname']:'';

}
private function connect(){
$this->link=@mysql_connect("{$this->host}:{$this->port}",$this->user,$this->pwd) or die('數據庫鏈接失敗');
}

private function setCharset(){
$sql = "set names '{$this->charset}'";
$this->query($sql);
}
private function selectDB(){
$sql = "use `{$this->dbname}`";
$this->query($sql);
}
private function __construct($config){
$this->initParam($config);
$this->connect();
$this->setCharset();
$this->selectDB();
}
private function __clone(){

}
public static function getInstance($config=array()) {
if(!self::$instance instanceof self)
self::$instance=new self($config);
return self::$instance;
}
public function query($sql){
if(!$result=mysql_query($sql,$this->link)){
echo 'sql語句執行失敗<br />';
exit;
}
return $result;
}
}
$config=array(
'host' => '127.0.0.1',
'user' => 'root',
'dbname' => 'accounts'
);
$db = Test::getInstance($config);
$sql = "select * from acc_wechat";
$info = $db->query($sql);
while($rows = mysql_fetch_row($info)){
//echo $rows[1].'<br>';
//var_dump($rows);
echo $rows[0].'-'.$rows[1].'<br />';
}
var_dump($info);
?>算法

經過如下代碼,咱們就大致瞭解了:單例的原理及實際運用。sql

 

工廠模式:數據庫

工廠模式能夠這樣來歸納:工廠裏面已經把你所須要的東西都準備好了,要什麼本身拿就行。函數

集體實現代碼以下:測試

<?phpfetch

//要實現的接口網站

interface BaseClass{

  public function say();

}

//實現接口類1

class Man implements BaseClass{

  function say(){

    return 'I'm Man.';

  }

}

//實現接口類2

class Women implements BaseClass{

  function say(){

    return 'I'm Women.';

  }

}

//構建工廠類

class Factory{

  public static function man(){

    return new Man();

  }

  public static function  Women(){

    return new Women();

  }

}

//獲取工廠中Man這個類

$man=Factory::man();

//調用Man類中的say方法

$man->say();

//獲取工廠中Women這個類

$women=Factory::women();

//調用Women類中的say方法

$women->say();

?>

以上就是工廠模式的實現過程。

 

策略模式:

這個我也不知道該怎麼形容,直接上代碼吧。

<?php

//接口類(抽象策略角色)

interface BaseClass{

  public function name();

}

//實現接口類1(環境角色1(對抽象策略角色的引用))

class XiaoMing implements BaseClass{

  function name(){

    return 'My name is XiaoMing.';

  }

}

//實現接口類2(環境角色2(對抽象策略角色的引用))

class XiaoHong implements BaseClass{

  function name(){

    reutrn 'My name is XiaoHong.';

  }

}

//構建具體策略角色

class CeLve{

  public function call($object){

    return $object->name();

  }

}

//實例化策略類

$obj = new CeLve();

//傳入小明類並調用name方法,打印出結果

echo $obj->call(new XiaoMing());

//傳入小紅類並調用name方法,打印出結果

echo $obj->call(new XiaoHong());

?>

 

關於工廠模式和策略 模式,有如下總結。

該總結出自:簡單工廠模式與策略模式的區別

工廠(Factory)模式咱們能夠作以下理解,假設有一個Audi的公司生產汽車(彷佛也不用假設了),它掌握一項核心的技術就是生產汽車,另外一方面,它生產的汽車是有不一樣型號的,而且在 不一樣的生產線上進行組裝。當客戶經過銷售部門進行預約後,Audi公司將在指定的生產線上爲客戶生產出它所須要的汽車。

策略(Strategy)模式在結構上與工廠模式相似,惟一的區別是工廠模式實例化一個產品的操做是在服務端來作的 ,換句話說客戶端傳達給服務端的只是某種標識,服務端根據該標識實例化一個對象。而策略模式的客戶端傳達給服務端的是一個實例 ,服務端只是將該實例拿過去在服務端的環境裏執行該實例的方法。這就比如一個對汽車不甚瞭解的人去買車,他在那一比劃,說要什麼什麼樣的,銷售部門根據他的這個「比劃」來造成一份訂單,這就是工廠模式下的工做方式。而策略模式下那個顧客就是個行家,他本身給出了訂單的詳細信息,銷售部門只是轉了一下手就交給生產部門去作了。經過兩相對比,咱們不難發現,採用工廠模式必須提供足夠靈活的銷售部門,若是用戶有了新的需求,銷售部門必須立刻意識到這樣才能夠作出合適的訂單。因此倘一款新車出來了,生產部門和銷售部門都須要更新,對顧客來講也須要更新對新車的描述因此須要改動的地方有三處。而策略模式中的銷售部門工做比較固定,它只負責接受訂單並執行特定的幾個操做。當一款新車出來時,只須要對服務端的生產部門和客戶端的代碼進行更新,而不須要更新銷售部門的代碼。

技術支持:

簡單工廠和策略的基礎都是由於面向對象的封裝與多態。他們實現的思想都是先設定一個抽象的模型並從該模型派生出符合不一樣客戶需求的各類方法,並加以封裝。

 

 

簡單工廠模式能夠與策略模式結合。

簡單工廠模式須要客戶端認識 工廠類 和 抽象類的方法。

而策略模式簡單工廠模式的結合能夠把客戶端的判斷封裝在Context類的構造函數裏,這樣可讓客戶端只須要認識 Context 類就好了,更下降了耦合度。

 

例如簡單工廠模式:

$a=Factory::func('123');

$a->show();

客戶須要知道工廠類的建立方法func與類名Factory.還須要知道返回的類繼承的抽象類或者接口定義的方法show()的用法。

 

而策略模式中

$a=new Context(new aClass(123));

$a->show();

仍是須要客戶端認識Context類與傳入構造函數的參數類,因此能夠加以改造,將策略模式與簡單工廠模式結合起來,讓構造函數接受一個條件變量,在構造函數中根據這個變量來決定產生的具體實例。

$a = new Context(123);

$a->show();

客戶只須要認識Context類就能夠了。

 

策略模式的重點在於讓算法家族間的算法能夠相互替換,引發的變化不會影響到使用算法的客戶。

相關文章
相關標籤/搜索