php設(shè)計(jì)模式小結(jié)
1、單例模式
所謂單例模式,也就是在任何時(shí)候,應(yīng)用程序中只會(huì)有這個(gè)類(lèi)的一個(gè)實(shí)例存在。常見(jiàn)的,我們用到單例模式只讓一個(gè)對(duì)象去訪(fǎng)問(wèn)數(shù)據(jù)庫(kù),從而防止打開(kāi)多個(gè)數(shù)據(jù)庫(kù)連接。要實(shí)現(xiàn)一個(gè)單例類(lèi)應(yīng)包括以下幾點(diǎn):
和普通類(lèi)不同,單例類(lèi)不能被直接實(shí)例化,只能是由自身實(shí)例化。因此,要獲得這樣的限制效果,構(gòu)造函數(shù)必須標(biāo)記為private。
要讓單例類(lèi)不被直接實(shí)例化而能起到作用,就必須為其提供這樣的一個(gè)實(shí)例。因此,就必須要讓單例類(lèi)擁有一個(gè)能保存類(lèi)的實(shí)例的私有靜態(tài)成員變量和對(duì)應(yīng)的一個(gè)能訪(fǎng)問(wèn)到實(shí)例的公共靜態(tài)方法。
在PHP中,為防止對(duì)單例類(lèi)對(duì)象的克隆來(lái)打破單例類(lèi)的上述實(shí)現(xiàn)形式,通常還為基提供一個(gè)空的私有__clone()方法。
下面是一個(gè)基本的單例模式:
class SingetonBasic {
private static $instance;
// other vars..
private function __construct() {
// do construct..
}
private function __clone() {}
public static function getInstance() {
if (!(self::$instance instanceof self)) {
self::$instance = new self();
}
return self::$instance;
}
// other functions..
}
$a = SingetonBasic::getInstance();
$b = SingetonBasic::getInstance();
var_dump($a === $b);
2、工廠(chǎng)模式
工廠(chǎng)模式在于可以根據(jù)輸入?yún)?shù)或者應(yīng)用程序配置的不同來(lái)創(chuàng)建一種專(zhuān)門(mén)用來(lái)實(shí)現(xiàn)化并返回其它類(lèi)的實(shí)例的類(lèi)。下面是一個(gè)最基本的工廠(chǎng)模式:
class FactoryBasic {
public static function create($config) {
}
}
比如這里是一個(gè)描述形狀對(duì)象的工廠(chǎng),它希望根據(jù)傳入的參數(shù)個(gè)數(shù)不同來(lái)創(chuàng)建不同的形狀。
// 定義形狀的公共功能:獲取周長(zhǎng)和面積。
interface IShape {
function getCircum();
function getArea();
}
// 定義矩形類(lèi)
class Rectangle implements IShape {
private $width, $height;
public function __construct($width, $height) {
$this->width = $width;
$this->height = $height;
}
public function getCircum() {
return 2 * ($this->width + $this->height);
}
public function getArea() {
return $this->width * $this->height;
}
}
// 定義圓類(lèi)
class Circle implements IShape {
private $radii;
public function __construct($radii) {
$this->radii = $radii;
}
public function getCircum() {
return 2 * M_PI * $this->radii;
}
public function getArea() {
return M_PI * pow($this->radii, 2);
}
}
// 根據(jù)傳入的參數(shù)個(gè)數(shù)不同來(lái)創(chuàng)建不同的形狀。
class FactoryShape {
public static function create() {
switch (func_num_args()) {
case 1:
return new Circle(func_get_arg(0));
break;
case 2:
return new Rectangle(func_get_arg(0), func_get_arg(1));
break;
}
}
}
// 矩形對(duì)象
$c = FactoryShape::create(4, 2);
var_dump($c->getArea());
// 圓對(duì)象
$o = FactoryShape::create(2);
var_dump($o->getArea());
使用工廠(chǎng)模式使得在調(diào)用方法時(shí)變得更容易,因?yàn)樗挥幸粋€(gè)類(lèi)和一個(gè)方法,若沒(méi)有使用工廠(chǎng)模式,則要在調(diào)用時(shí)決定應(yīng)該調(diào)用哪個(gè)類(lèi)和哪個(gè)方法;使用工廠(chǎng)模式還使得未來(lái)對(duì)應(yīng)用程序做改變時(shí)更加容易,比如要增加一種形狀的支持,只需要修改工廠(chǎng)類(lèi)中的create()一個(gè)方法,而沒(méi)有使用工廠(chǎng)模式,則要修改調(diào)用形狀的代碼塊。
3、觀(guān)察者模式
觀(guān)察者模式為您提供了避免組件之間緊密耦合的另一種方法。該模式非常簡(jiǎn)單:一個(gè)對(duì)象通過(guò)添加一個(gè)方法(該方法允許另一個(gè)對(duì)象,即觀(guān)察者注冊(cè)自己)使本身變得可觀(guān)察。當(dāng)可觀(guān)察的對(duì)象更改時(shí),它會(huì)將消息發(fā)送到已注冊(cè)的觀(guān)察者。這些觀(guān)察者使用該信息執(zhí)行的操作與可觀(guān)察的對(duì)象無(wú)關(guān)。結(jié)果是對(duì)象可以相互對(duì)話(huà),而不必了解原因。
一個(gè)簡(jiǎn)單的示例:當(dāng)聽(tīng)眾在收聽(tīng)電臺(tái)時(shí)(即電臺(tái)加入一個(gè)新聽(tīng)眾),它將發(fā)送出一條提示消息,通過(guò)發(fā)送消息的日志觀(guān)察者可以觀(guān)察這些消息。
// 觀(guān)察者接口
interface IObserver {
function onListen($sender, $args);
function getName();
}
// 可被觀(guān)察接口
interface IObservable {
function addObserver($observer);
function removeObserver($observer_name);
}
// 觀(guān)察者類(lèi)
abstract class Observer implements IObserver {
protected $name;
public function getName() {
return $this->name;
}
}
// 可被觀(guān)察類(lèi)
class Observable implements IObservable {
protected $observers = array();
public function addObserver($observer) {
if (!($observer instanceof IObserver)) {
return;
}
$this->observers[] = $observer;
}
public function removeObserver($observer_name) {
foreach ($this->observers as $index => $observer) {
if ($observer->getName() === $observer_name) {
array_splice($this->observers, $index, 1);
return;
}
}
}
}
// 模擬一個(gè)可以被觀(guān)察的類(lèi):RadioStation
class RadioStation extends Observable {
public function addListener($listener) {
foreach ($this->observers as $observer) {
$observer->onListen($this, $listener);
}
}
}
// 模擬一個(gè)觀(guān)察者類(lèi)
class RadioStationLogger extends Observer {
protected $name = 'logger';
public function onListen($sender, $args) {
echo $args, ' join the radiostation.<br/>';
}
}
// 模擬另外一個(gè)觀(guān)察者類(lèi)
class OtherObserver extends Observer {
protected $name = 'other';
public function onListen($sender, $args) {
echo 'other observer..<br/>';
}
}
$rs = new RadioStation();
// 注入觀(guān)察者
$rs->addObserver(new RadioStationLogger());
$rs->addObserver(new OtherObserver());
// 移除觀(guān)察者
$rs->removeObserver('other');
// 可以看到觀(guān)察到的信息
$rs->addListener('cctv');
相關(guān)文章
php正則匹配文章中的遠(yuǎn)程圖片地址并下載圖片至本地
這篇文章主要介紹了php正則匹配文章中的遠(yuǎn)程圖片地址并下載圖片至本地的實(shí)現(xiàn)技巧,可實(shí)現(xiàn)采集并保存遠(yuǎn)程圖片的功能,是非常實(shí)用的技巧,感興趣的小伙伴可以參考一下2015-09-09PHP實(shí)現(xiàn)多級(jí)分類(lèi)生成樹(shù)的方法示例
這篇文章主要介紹了PHP實(shí)現(xiàn)多級(jí)分類(lèi)生成樹(shù)的方法,涉及php+mysql數(shù)據(jù)庫(kù)操作及數(shù)組與字符串遍歷、替換、組合等相關(guān)操作技巧,需要的朋友可以參考下2017-02-02PHP數(shù)據(jù)庫(kù)處理封裝類(lèi)實(shí)例
這篇文章主要介紹了PHP數(shù)據(jù)庫(kù)處理封裝類(lèi),結(jié)合完整實(shí)例形式分析了php基于mysqli封裝的數(shù)據(jù)庫(kù)連接及增刪改查等操作,需要的朋友可以參考下2016-12-12淺析PHP程序防止ddos,dns,集群服務(wù)器攻擊的解決辦法
本篇文章是對(duì)PHP程序防止ddos,dns,集群服務(wù)器攻擊的解決辦法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06利用php獲取標(biāo)準(zhǔn)北京時(shí)間的方法
這篇文章主要介紹了如何利用php獲取標(biāo)準(zhǔn)北京時(shí)間的方法,文中有詳細(xì)的代碼示例供大家參考,對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-04-04CKEditor4結(jié)合php實(shí)現(xiàn)上傳圖片功能
ckedit4是沒(méi)有圖片上傳功能的,單我們可以通過(guò)配置?config.js?文件來(lái)設(shè)置圖片上傳的接口,然后結(jié)合后端程序?qū)崿F(xiàn)圖片上傳,本文講解CKEditor4結(jié)合php實(shí)現(xiàn)上傳圖片功能的方法2024-03-03php中ob(Output Buffer 輸出緩沖)函數(shù)使用方法
php中ob(Output Buffer 輸出緩沖)函數(shù)使用方法...2007-07-07PHP JSON格式數(shù)據(jù)交互實(shí)例代碼詳解
此前我寫(xiě)了不少在PHP網(wǎng)站開(kāi)發(fā)中應(yīng)用XML進(jìn)行數(shù)據(jù)交互的實(shí)例,這兩天通過(guò)PHP解析JSON并進(jìn)行交互的實(shí)例學(xué)習(xí)和了解了JSON在PHP中的應(yīng)用,感覺(jué)非常方便。2011-01-01