首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

關鍵詞匹配專案實戰日記(十八):重構提煉方法與搬移職責

     編輯:PHP 相關知識

關鍵詞匹配專案實戰日記(十八):重構提煉方法與搬移職責

系列第十八天。技術總監(於老大)對代碼品質要求嚴格,透過代碼審查引導小帥帥運用重構技法改善設計。

一、背景:三層 foreach 的代碼異味

LinklistCharListHandle::exec() 原始碼包含三層巢狀 foreach,於老大一眼指出結構混亂,要求重構。

二、第一輪重構:Extract Method(提煉函數)

小帥帥將內層邏輯提煉為 propertiesTransferCharlist() 與 addCores() 兩個方法:

class LinklistCharListHandle extends CharListHandle {
    public function exec() {
        $sql = "select word from category_linklist where cid='{$this->selectorItem->cid}'";
        $linklist = DB::makeArray($sql);
        foreach ($linklist as $strWords) {
            $words = explode(",", $strWords);
            $this->propertiesTransferCharlist($words);
        }
    }
    public function propertiesTransferCharlist($linkWords) {
        $properties = $this->selectorItem->getProperties();
        foreach ($properties as $property) {
            $this->charlist->addCore($property->value);
            if (in_array($property->value, $linkWords)) {
                $this->addCores($linkWords);
            }
        }
    }
    public function addCores($words) {
        foreach ($words as $char) {
            $this->charlist->addCore($char);
        }
    }
}

代碼可讀性提升,但於老大提出兩個關鍵問題:

  1. propertiesTransferCharlist 為何需要傳參數?
  2. addCores 屬於哪個類別的職責?

三、第二輪重構:Move Method(搬移函數)

小帥帥將 addCores 搬移至 CharList 類別,符合「資料與操作資料的方法應在一起」的高內聚原則:

class CharList {
    private $core = [];
    private $blacklist = [];
    public function addCore($char) {
        if (!in_array($char, $this->core)) $this->core[] = $char;
    }
    public function addCores($words) {
        foreach ($words as $char) $this->addCore($char);
    }
    public function getCore() { return $this->core; }
    public function addBlacklist($char) { /* ... */ }
    public function getBlacklist() { return $this->blacklist; }
}

四、第三輪重構:於老大的終極版本

於老大引入靜態快取、單一職責、封裝查詢邏輯,最終版本:

class LinklistCharListHandle extends CharListHandle {
    private static $linklist = [];
    public function exec() {
        $this->propertiesTransferCharlist();
    }
    public static function linklist($cid) {
        if (!isset(self::$linklist[$cid])) {
            $sql = "select word from category_linklist where cid='$cid'";
            self::$linklist[$cid] = DB::makeArray($sql);
        }
        return self::$linklist[$cid];
    }
    public function propertiesTransferCharlist() {
        $properties = $this->selectorItem->getProperties();
        foreach ($properties as $property) {
            $this->charlist->addCore($property->value);
            $this->extendCharlist($property->value);
        }
    }
    public function extendCharlist($char) {
        $linklist = self::linklist($this->selectorItem->cid);
        foreach ($linklist as $strWords) {
            $words = explode(",", $strWords);
            if (in_array($char, $words)) {
                $this->charlist->addCores($words);
            }
        }
    }
}

五、重構精華總結

重構手法應用場景效益
Extract Method過長函數、重複邏輯、嵌套過深提升可讀性、可複用、可測試
Move Method方法更常使用另一類別的資料/行為高內聚、低耦合、職責清晰
Replace Parameter with Query參數可由接收者自行查詢簡化介面、減少耦合
Introduce Caching重複昂貴查詢效能提升、資源節省

六、感悟

「代碼隨便改變下,區別這麼大,以前為啥從來沒有這感覺。」—— 小帥帥

重構不是重寫,而是在保持行為不變前提下,通過微小步驟持續改善設計。技術總監的價值不在於寫多少代碼,而在於建立標準、引導團隊產出可維護的高品質代碼。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved