1.定義
工廠方法模式(Factory Method Pattern)是一種創建型設計模式,它提供了一種創建對象的接口,而不是通過具體類來實例化對象。工廠方法模式的主要作用是讓子類決定實例化哪一個類,從而實現對象創建的延遲到具體子類中進行。
2.主要作用
作用就是使設計更加靈活和可擴展。通過這種方式,父類無需知道具體要創建的對象是哪一種,這樣就提高了系統的可擴展性和可維護性(符合開閉原則)一切優秀的模式都向設計原則看齊。
3.解決的問題
說到解決的問題,這里就不得不提下簡單工廠模式了,什么?你不知道簡單工廠模式是什么,沒關系,先來看下定義:
簡單工廠模式是一種創建型模式,它定義了一個工廠類,該類包含一個方法,根據給定的參數來返回不同類的實例。
客戶端通過向工廠類傳遞參數來獲取所需的具體對象實例,而不需要直接實例化對象。
包含角色:
-
工廠類(Factory)
:負責根據客戶端的請求創建相應的對象。 -
產品類(Product)
:被創建的對象的基類或接口。具體的產品類是工廠類所創建的對象類型。 -
具體產品類(Concrete Product)
:實現了產品接口的具體對象類,由工廠類根據客戶端的需求創建和返回。
UML類圖:
代碼示例:
public class LoggerFactory {public static Logger createLogger(String logType) {if ("Console".equals(logType)) {return new ConsoleLogger();} else if ("File".equals(logType)) {return new FileLogger();} else if ("Remote".equals(logType)) {return new RemoteLogger();} else {throw new IllegalArgumentException("Unsupported log type");}}
}
通過 LoggerFactory.createLogger("Console")
、LoggerFactory.createLogger("File")
或者 LoggerFactory.createLogger("Remote")
來獲取不同類型的日志記錄器,這種方式就是簡單工廠模式,熟不熟悉,在你的項目中是不是也使用過這種模式呢,由于不難理解所以稱為簡單。
簡單是簡單,當然他也有一些弊端,如果上面示例代碼中 Logger 抽象類中只有打印一個方法,后續需要新增保存日志,過濾日志… 問題就暴露出來了,簡單來說就是 簡單工廠模式違反了開閉原則,即對擴展開放,對修改關閉。
工廠方法模式解決了簡單工廠模式的哪些問題?
- 開閉原則:工廠方法模式遵循開閉原則,通過定義抽象工廠類和具體工廠類的繼承關系,新增產品時只需增加具體工廠類和產品類,而無需修改現有代碼,降低了系統的耦合性。
- 擴展性:工廠方法模式支持更多的靈活性,每個具體的工廠類只負責創建對應的產品,符合單一職責原則,代碼更加清晰和可維護。
- 維護性:由于工廠方法模式將對象的創建延遲到子類中,避免了簡單工廠模式中工廠類集中所有產品創建邏輯的問題,使代碼結構更加清晰和可擴展。
簡單來說,就是解決了簡單工廠模式中集中創建邏輯和不符合開閉原則的問題,提高了代碼的靈活性和可維護性。
4.模式原理
包含角色:
產品(Product)
:定義產品的接口。具體產品(ConcreteProduct)
:實現產品接口的具體類。工廠(Factory)
:定義創建產品對象的接口。具體工廠(ConcreteFactory)
:實現創建產品對象的具體類。
UML類圖:
// 定義產品接口
public interface Product {String operation();
}// 定義具體產品類
public class ConcreteProductA implements Product {@Overridepublic String operation() {return "產品A";}
}public class ConcreteProductB implements Product {@Overridepublic String operation() {return "產品B";}
}// 定義工廠接口
public abstract class Creator {// 工廠方法public abstract Product factoryMethod();// 其它操作方法public String someOperation() {Product product = factoryMethod();return product.operation();}
}// 定義具體工廠類
public class ConcreteCreatorA extends Creator {@Overridepublic Product factoryMethod() {return new ConcreteProductA();}
}public class ConcreteCreatorB extends Creator {@Overridepublic Product factoryMethod() {return new ConcreteProductB();}
}// 客戶端代碼
public class Client {public static void main(String[] args) {clientCode(new ConcreteCreatorA());clientCode(new ConcreteCreatorB());}public static void clientCode(Creator creator) {System.out.println("Client: " + creator.someOperation());}
}
打印:
Client: 產品A
Client: 產品B
相較簡單工廠模式 增加了一個具體工廠角色,每增加一個具體產品,需要同時增加一個具體工廠類。所以說各有優缺點吧。
4.優缺點
優點:
- 遵循開閉原則:可以在引入新產品時不修改現有代碼。
- 遵循單一職責原則:將產品對象的創建邏輯封裝在工廠類中。
- 減少代碼耦合:客戶端不直接依賴于具體類,只依賴于抽象產品和工廠接口(符合依賴倒置原則)。.
缺點:
- 增加代碼復雜性:每增加一個具體產品,需要同時增加一個具體工廠類。
- 類的數量增加:每個具體產品都需要一個對應的具體工廠,會導致類的數量增加。
5.應用場景
- 需要創建復雜對象:當對象的創建過程比較復雜,且需要多步操作時。
- 產品種類多且類型不確定:當系統中需要創建的產品種類較多且類型在運行時才確定時。
- 需要對創建過程進行控制:當需要對對象的創建過程進行控制,并且希望將控制邏輯封裝起來時。
emm… 其實還是簡單工廠模式 應用場景更廣泛些,畢竟簡單好用🤭
總結比較:
- 簡單工廠模式適合于對象類型較少且不經常變化的場景,代碼較為簡單,但不符合開閉原則,難以擴展新的產品類型。
- 工廠方法模式更加符合開閉原則,通過增加新的具體工廠和具體產品類來擴展系統功能,但會增加系統中類的個數和復雜度。
6.總結
工廠模式解決了簡單工廠模式中集中創建邏輯和不符合開閉原則的問題,但同時自身也有一些弊端,但通過合理應用工廠方法模式,在特定的場景可以有效地提高系統的可維護性和擴展性。
設計模式沒有最好的,只有最適合的,大家在選用時,要權衡利弊,避免過度設計!