「呼叫端傳個網址進來,判斷一下網域是哪個站台,new 對應的爬蟲就好了吧?」
問題是:這個判斷邏輯只寫一次,很快就會被複製到第二個、第三個呼叫端。今天新增一個來源站,就要回頭把每一處判斷邏輯都加上一個 elif——而且很容易漏掉某一處。
❌ 反例:每個呼叫端各自判斷
def process(url):
domain = urlparse(url).netloc
if 'site-b' in domain:
crawler = SiteB()
else:
crawler = SiteA()
...
def another_process(url):
domain = urlparse(url).netloc
if 'site-b' in domain: # 同樣的判斷又寫一次
crawler = SiteB()
else:
crawler = SiteA()
...
✅ 正例:Factory 集中負責「該用哪個」
class CrawlerFactory:
def create(self, url: str) -> Crawler:
domain = urlparse(url).netloc
if 'site-b' in domain:
return SiteB()
return SiteA()
def process(url, factory: CrawlerFactory):
crawler = factory.create(url)
...
新增一個來源站時,只要改 CrawlerFactory.create() 這一個地方,所有呼叫端不用動一行程式碼。
嚴格來說,這裡示範的是集中判斷邏輯的 Simple Factory 寫法(一個方法裡用條件判斷回傳不同類別),跟 GoF 定義的 Factory Method(由子類別各自透過多型決定要建立哪個物件,而不是集中在一處 if-else)並不是同一個模式。業界口語上很常把兩者都泛稱「Factory Pattern」,這裡沿用這個習慣說法,但值得知道兩者的差異,對照 GoF 原典時才不會搞混。
「該用哪個爬蟲」聽起來像是個瑣碎的 if-else,但它是一個有明確輸入輸出、值得獨立驗證的邏輯單元:給定一個網址,應該回傳哪個類別的實例。集中成一個 Factory 之後,測試也集中成一份——不用在每個呼叫端各自驗證一次判斷邏輯對不對。
你的專案裡有沒有「該用哪個實作」這種判斷散落在多個呼叫端的情況?如果現在要新增一種情境,你要改幾個地方?
明天進入一個真實踩過的坑:從頁面裡取出 M3U8 位置時,那段資料被包在一段字串化的 JSON 裡,用正規表達式硬解析容易在哪裡出包。