小帥帥完成了關鍵詞匹配的初版邏輯:根據淘寶商品標題/屬性中的「男裝/女裝/情侶裝/童裝」關鍵字,動態構建核心詞與黑名單,再拼接 SQL 查詢。代碼雖能跑通,卻被架構師于老大一頓批評:
if-else 鏈,擴展新品類需改動核心邏輯(違反開閉原則)<?php
// 1. 領域模型:封裝淘寶 API 返回數據
class SelectorItem {
private $item;
public function __construct($item) { $this->item = $item; }
public function __get($name) { return $this->item->$name ?? null; }
public static function createFromApi($num_iid): self {
$client = new TopClient(); // 省略配置
$req = new ItemGetRequest();
$req->setFields('props_name,property_alias,detail_url,cid,title');
$req->setNumIid($num_iid);
$resp = $client->execute($req);
if (isset($resp->code)) throw new Exception($resp->msg, $resp->code);
return new self($resp->item);
}
}
// 2. 關鍵字容器
class CharList {
private $core = [], $blacklist = [];
public function addCore($c) { if (!in_array($c, $this->core)) $this->core[] = $c; }
public function addBlacklist($c) { if (!in_array($c, $this->blacklist)) $this->blacklist[] = $c; }
public function getCore() { return $this->core; }
public function getBlacklist() { return $this->blacklist; }
}
// 3. 策略接口
abstract class CharListHandle {
protected $charlist;
public function __construct(CharList $cl) { $this->charlist = $cl; }
abstract public function exec();
}
// 4. 具體策略
class MenCharListHandle extends CharListHandle {
public function exec() {
$this->charlist->addCore('男裝');
$this->charlist->addBlacklist('女');
}
}
class WomenCharListHandle extends CharListHandle { /* ... */ }
class LoversCharListHandle extends CharListHandle { /* ... */ }
class ChildrenCharListHandle extends CharListHandle { /* ... */ }
// 5. 選擇器:策略註冊表 + 工廠方法
class Selector {
private static $map = [
'男裝' => MenCharListHandle::class,
'女裝' => WomenCharListHandle::class,
'情侶裝' => LoversCharListHandle::class,
'童裝' => ChildrenCharListHandle::class,
];
public static function select($num_iid) {
$item = SelectorItem::createFromApi($num_iid);
$matchTitle = $item->title . $item->props_name;
$charlist = new CharList();
foreach (self::$map as $keyword => $handlerClass) {
if (preg_match("/$keyword/", $matchTitle)) {
$handler = self::createHandler($handlerClass, $charlist);
$handler->exec();
}
}
// 後續:用 $charlist->getCore()/getBlacklist() 構建查詢...
}
private static function createHandler(string $class, CharList $cl): CharListHandle {
if (class_exists($class)) return new $class($cl);
throw new Exception("Handler $class not found");
}
}
$map,零修改核心流程。createHandler 統一實例化邏輯,支援異常處理與擴展(如依賴注入容器)。__get:讓 $item->title 透明代理到底層數組,調用端無感知。「優秀的程序員寫出可讀、可維護、可擴展的代碼;普通程序員只是寫出能跑通的代碼。」
小帥帥雖然最初不服,但通過這次重構見識到設計模式在實際業務中的威力,決定系統學習《設計模式》並嘗試在後續需求中主動應用。