日韩天天综合网_野战两个奶头被亲到高潮_亚洲日韩欧美精品综合_av女人天堂污污污_视频一区**字幕无弹窗_国产亚洲欧美小视频_国内性爱精品在线免费视频_国产一级电影在线播放_日韩欧美内地福利_亚洲一二三不卡片区

《PHP設(shè)計(jì)模式介紹》第一章 編程慣用法(2)_PHP教程

編輯Tag賺U幣
教程Tag:暫無(wú)Tag,歡迎添加,賺取U幣!

推薦:《PHP設(shè)計(jì)模式介紹》導(dǎo)言
當(dāng)你在不斷的試圖從你的應(yīng)用程序中發(fā)現(xiàn)新的特征時(shí),你是否發(fā)現(xiàn)你提出的解決方法和一些以前你已經(jīng)實(shí)現(xiàn)的東西是如此的類(lèi)似呢?如果你是一個(gè)程序員(即使你才 開(kāi)始很短的時(shí)間),你都可能回答&ldqu

重構(gòu)

即使最有思想性且最熟練的程序員也不能預(yù)見(jiàn)一個(gè)軟件項(xiàng)目中的任何細(xì)微之處。問(wèn)題總是出乎意外的出現(xiàn),需求也可能在變化,結(jié)果是代碼被優(yōu)化,共享然后代替。

重構(gòu)是一個(gè)慣用的方法:檢查你所有的代碼,找出其中能統(tǒng)一化和簡(jiǎn)單化的共同或者類(lèi)似之處,使得你的代碼更加容易維護(hù)和擴(kuò)展。重構(gòu)也包括探索一個(gè)設(shè)計(jì)模式是否能夠應(yīng)用到這個(gè)具體的問(wèn)題上——這也能使解決方案簡(jiǎn)單化。

重構(gòu),簡(jiǎn)單點(diǎn)說(shuō)是重命名一個(gè)屬性或者方法,復(fù)雜點(diǎn)說(shuō)是壓縮一個(gè)已有的類(lèi)。改變你的代碼使得它符合一個(gè)或者更多的設(shè)計(jì)模式是另外一種重構(gòu)——讀完這本書(shū)后,你可能會(huì)去實(shí)現(xiàn)的。

沒(méi)有什么能比例子來(lái)更好的解釋重構(gòu)了!

讓我們考慮兩個(gè)簡(jiǎn)單的類(lèi):CartLine和Cart。CartLine記錄了購(gòu)物車(chē)?yán)锩婷總(gè)項(xiàng)目的單件價(jià)格和數(shù)量。比如CartLine可能記錄著“四見(jiàn)紅色的polo襯衣,每件19.99$”。Cart 是一個(gè)容器,用來(lái)裝載一個(gè)或者更多的CartLine對(duì)象并執(zhí)行一些相關(guān)的計(jì)算工作,比如購(gòu)物車(chē)?yán)锩娴乃猩唐返目偦ㄙM(fèi)。

下面是CartLine和Cart的簡(jiǎn)單實(shí)現(xiàn):

// PHP5
class CartLine {
public $price = 0;
public $qty = 0;
}
class Cart {
protected $lines = array();
public function addLine($line) {
$this->lines[] = $line;
}
public function calcTotal() {
$total = 0;
// add totals for each line
foreach($this->lines as $line) {
$total = $line->price * $line->qty;
}
// add sales tax
$total *= 1.07;
return $total;
}
}

重構(gòu)的第一步必須有足夠的測(cè)試來(lái)覆蓋你所有的代碼。這樣才能保證你修改的代碼不能產(chǎn)生和你原來(lái)代碼不同的結(jié)果。順便提一下,除非你改變了需求(你代碼期望的結(jié)果)或者在測(cè)試實(shí)例中發(fā)現(xiàn)了錯(cuò)誤,你的測(cè)試代碼是是不能改變的。

下面是一個(gè)測(cè)試CartLine和Cart的例子,它在重構(gòu)的過(guò)程中是不會(huì)改變的。

function TestCart() {
$line1 = new CartLine;
$line1->price = 12; $line1->qty = 2;
$line2 = new CartLine;
$line2->price = 7.5; $line2->qty = 3;
$line3 = new CartLine;
$line3->price = 8.25; $line3->qty = 1;
$cart = new Cart;
$cart->addLine($line1);
$cart->addLine($line2);
$cart->addLine($line3);
$this->assertEqual(
(12*2 7.5*3 8.25) * 1.07,
$cart->calcTotal());
}

看著上面的代碼,你可能會(huì)發(fā)現(xiàn)它們有一些“code smells”(代碼臭味)——有著古怪的樣子而且看起來(lái)好像是有問(wèn)題的代碼——它們就像重構(gòu)的候選項(xiàng)。(更多關(guān)于code smells的資料請(qǐng)看http://c2.com/cgi/wiki?codesmell)。兩個(gè)最直接的重構(gòu)候選者是注釋和計(jì)算(與銷(xiāo)售稅等相關(guān)的計(jì)算)。重構(gòu)的一種形式:析取函數(shù)(Extract Method)將把這些難看的代碼從cart::calcTotal()中提取出來(lái),然后用一個(gè)合適的方法來(lái)替代它,從而使得代碼更加簡(jiǎn)潔。

比如,你可以增加兩個(gè)計(jì)算方法:lineTotal()和calcSalesTax():

protected function lineTotal($line) {
return $line->price * $line->qty;
}
protected function calcSalesTax($amount) {
return $amount * 0.07;
}

現(xiàn)在你可以重寫(xiě)calcTotal()函數(shù):

public function calcTotal() {
$total = 0;
foreach($this->lines as $line) {
$total = $this->lineTotal($line);
}
$total = $this->calcSalesTax($total);
return $total;
}

到目前為止的改動(dòng)都是有意義的(至少在這個(gè)例子的上下文中),它對(duì)于再次暫停和運(yùn)行這些代碼來(lái)驗(yàn)證結(jié)果依然正確是很有幫助的。記得,一個(gè)綠色的成功條的顯示出來(lái)了�。ㄗg者注:本章開(kāi)始時(shí),作者提及到:綠色的條意味著測(cè)試都通過(guò)了。)

然而,目前的代碼依然有一些可以挑剔的地方。其中一個(gè)就是在新方法lineTotal()中存取公共屬性。很明顯計(jì)算每行的之和的責(zé)任不應(yīng)該屬于Cart類(lèi),而應(yīng)該在類(lèi)CartLine里面實(shí)現(xiàn)。

再次重構(gòu),在CartLine中增加一個(gè)新的方法total()用來(lái)計(jì)算訂單里面的每個(gè)項(xiàng)目的長(zhǎng)期價(jià)錢(qián)。

public function total() {
return $this->price * $this->qty;
}

然后從類(lèi)Cart中移除方法lineTotal(),并改變calcTotal()方法來(lái)使用新的cartLine::Total()方法。重新運(yùn)行這個(gè)測(cè)試,你依然會(huì)發(fā)現(xiàn)結(jié)果是綠色條。

全新重構(gòu)后的代碼就是這樣:

class CartLine {
public $price = 0;
public $qty = 0;
public function total() {
return $this->price * $this->qty;
}
}
class Cart {
protected $lines = array();
public function addLine($line) {
$this->lines[] = $line;
}
public function calcTotal() {
$total = 0;
foreach($this->lines as $line) {
$total = $line->total();
}
$total = $this->calcSalesTax($total);
return $total;
}
protected function calcSalesTax($amount) {
return $amount * 0.07;
}
}

現(xiàn)在這代碼不再需要每行注釋了,因?yàn)榇a本身更好的說(shuō)明了每行的功能。這些新的方法,更好的封裝了計(jì)算這個(gè)功能,也更加容易適應(yīng)將來(lái)的變化。(比如說(shuō),考慮不同大的銷(xiāo)售稅率)。另外,這些類(lèi)也更加平衡,更容易維護(hù)。

這個(gè)例子顯然是微不足道的,但是希望你能從中推斷并預(yù)想出如何重構(gòu)你自己的代碼。

在編碼的時(shí)候,你應(yīng)該有出于兩種模式中的一種:增加新的特征或者重構(gòu)代碼。當(dāng)在增加特征的時(shí)候,你要寫(xiě)測(cè)試和增加代碼。在重構(gòu)的時(shí)候,你要改變你原有的代碼,并確保所有相關(guān)的測(cè)試依然能正確運(yùn)行。

關(guān)于重構(gòu)的主要參考資料有Martin Fowler著作的《重構(gòu):改進(jìn)原有代碼的設(shè)計(jì)》(Refactoring:Improving the Design of Existing Code)。用一些精簡(jiǎn)點(diǎn)來(lái)總結(jié)Fowler的書(shū),重構(gòu)的步驟如下所示:

定義需要重構(gòu)的代碼
有覆蓋所有代碼的測(cè)試
小步驟的工作
每步之后都運(yùn)行你的測(cè)試。編碼和測(cè)試都是相當(dāng)重復(fù)的——和編譯型語(yǔ)言相比,解釋型語(yǔ)言,比如PHP是容易很多的。
使用重構(gòu)來(lái)使你的代碼有更好的可讀性和可修改性。

分享:php escapeshellcmd多字節(jié)編碼漏洞
漏洞公告在http://www.sektioneins.de/advisories/SE-2008-03.txt PHP 5 = 5.2.5 PHP 4 = 4.4.8 一些允許如GBK,EUC-KR, SJIS等寬字節(jié)字符集的系統(tǒng)都可能受此影響,影響還是非常

來(lái)源:模板無(wú)憂(yōu)//所屬分類(lèi):PHP教程/更新時(shí)間:2008-08-22
相關(guān)PHP教程