在軟件設(shè)計制作領(lǐng)域,創(chuàng)建型設(shè)計模式旨在提供對象創(chuàng)建的靈活性和解耦性,其中工廠方法模式和抽象工廠模式是兩種尤為經(jīng)典且應(yīng)用廣泛的設(shè)計模式。雖然它們名稱相似,都圍繞“工廠”概念展開,但其設(shè)計理念、應(yīng)用場景和實現(xiàn)層次存在顯著區(qū)別。
一、工廠方法模式:專注于單一產(chǎn)品族的創(chuàng)建
工廠方法模式(Factory Method Pattern)定義了一個創(chuàng)建對象的接口,但將具體創(chuàng)建哪個類實例的決定推遲到子類中。其核心在于通過一個“工廠方法”來封裝對象的創(chuàng)建過程,使得客戶端代碼無需關(guān)心具體產(chǎn)品的實現(xiàn)細節(jié),只需依賴抽象接口。
例如,假設(shè)我們有一個“日志記錄器”抽象產(chǎn)品(Logger接口),它有兩個具體實現(xiàn):FileLogger(文件日志)和DatabaseLogger(數(shù)據(jù)庫日志)。工廠方法模式會定義一個LoggerFactory抽象類(或接口),其中聲明一個抽象的createLogger()方法。然后,針對不同的日志類型,派生出FileLoggerFactory和DatabaseLoggerFactory兩個具體工廠類,分別負責創(chuàng)建對應(yīng)的具體日志記錄器對象。這樣,當客戶端需要日志記錄器時,它只與LoggerFactory和Logger接口交互,具體創(chuàng)建哪一種日志器由具體的工廠子類決定,從而實現(xiàn)了創(chuàng)建邏輯與使用邏輯的分離,支持了“開閉原則”——新增一種日志類型時,只需添加新的具體產(chǎn)品和工廠類,無需修改現(xiàn)有客戶端代碼。
二、抽象工廠模式:構(gòu)建相關(guān)產(chǎn)品家族
抽象工廠模式(Abstract Factory Pattern)提供了一個接口,用于創(chuàng)建一系列相關(guān)或相互依賴的對象,而無需指定它們的具體類。它強調(diào)的是“產(chǎn)品家族”或“產(chǎn)品套件”的概念。一個抽象工廠能夠生產(chǎn)多個屬于同一主題或風格的不同類型產(chǎn)品。
以一個經(jīng)典的GUI界面組件為例:假設(shè)我們需要創(chuàng)建一套跨平臺的UI組件,包括按鈕(Button)和文本框(TextField)。對于Windows和Mac兩種操作系統(tǒng),它們各自有不同視覺風格的按鈕和文本框。抽象工廠模式會先定義兩個抽象產(chǎn)品接口:Button和TextField。然后,為每個平臺定義一個具體工廠,如WindowsFactory和MacFactory,每個具體工廠都能創(chuàng)建一整套匹配該平臺風格的產(chǎn)品(即WindowsButton + WindowsTextField,或MacButton + MacTextField)。抽象工廠接口(如GUIFactory)則聲明了創(chuàng)建按鈕和文本框的抽象方法(createButton(), createTextField())。客戶端代碼通過GUIFactory接口來獲取產(chǎn)品,從而完全與具體的平臺實現(xiàn)解耦。如果需要支持新的平臺(如Linux),只需新增一個具體工廠及其對應(yīng)的產(chǎn)品族即可,客戶端代碼基本不變。
三、核心區(qū)別與選擇
- 創(chuàng)建焦點:工廠方法模式聚焦于創(chuàng)建單一類型的產(chǎn)品對象,而抽象工廠模式專注于創(chuàng)建一系列相關(guān)的產(chǎn)品對象。
- 結(jié)構(gòu)復(fù)雜度:工廠方法模式通常只涉及一個產(chǎn)品層次結(jié)構(gòu)和一個對應(yīng)的創(chuàng)建者層次結(jié)構(gòu),結(jié)構(gòu)相對簡單。抽象工廠模式涉及多個產(chǎn)品等級結(jié)構(gòu)(多個產(chǎn)品接口及其實現(xiàn))和一個能夠生產(chǎn)所有這些產(chǎn)品的工廠接口及其實現(xiàn),結(jié)構(gòu)更為復(fù)雜。
- 擴展維度:
- 工廠方法模式擴展時,主要是擴展產(chǎn)品種類(新增具體產(chǎn)品)和對應(yīng)的創(chuàng)建者。
- 抽象工廠模式擴展時,主要有兩個維度:擴展產(chǎn)品家族(新增一個能生產(chǎn)整套新品類的具體工廠,如新增Linux支持)相對容易,符合開閉原則;但擴展產(chǎn)品族內(nèi)的產(chǎn)品種類(如在GUI組件中新增“復(fù)選框”產(chǎn)品)則較為困難,需要修改抽象工廠接口及其所有實現(xiàn),這可能違反開閉原則。
四、實際應(yīng)用啟示
在軟件設(shè)計制作實踐中,選擇哪種模式取決于具體的業(yè)務(wù)場景:
- 當系統(tǒng)需要創(chuàng)建的對象類型較為單一,且預(yù)計未來會有新的具體類型加入時,工廠方法模式是簡潔而有效的選擇。
- 當系統(tǒng)需要創(chuàng)建的是成組、成系列的相關(guān)對象,并且這些對象需要協(xié)同工作以確保一致性(如同一UI主題、同一數(shù)據(jù)庫系列驅(qū)動)時,抽象工廠模式更能勝任。它確保了從同一個工廠生產(chǎn)出來的對象是相互兼容的。
理解這兩種模式的精髓,有助于開發(fā)者在構(gòu)建靈活、可維護的軟件架構(gòu)時,做出更合適的設(shè)計決策,有效管理對象創(chuàng)建的復(fù)雜性。