本文節選自《設計模式就該這樣學》
1 工廠方法模式的應用場景
工廠方法模式主要適用於以下應用場景。
(1)建立物件需要大量重複的程式碼。
(2)客戶端(應用層)不依賴產品類例項如何被建立、實現等細節。
(3)一個類通過其子類來指定建立哪個物件。
2 工廠方法模式的UML類圖
工廠方法模式的UML類圖如下圖所示。
由上圖可以看到,抽象工廠模式主要包含4個角色。
(1)抽象工廠(Factory):是工廠方法模式的核心,與應用程式無關。任何在模式中建立的物件的工廠類必須實現這個介面。
(2)具體工廠(Concrete Factory):是實現抽象工廠介面的具體工廠類,包含與應用程式密切相關的邏輯,並且被應用程式呼叫以建立產品物件。
(3)抽象產品(Product):是工廠方法模式所建立的物件的超型別,也就是產品物件的共同父類或共同擁有的介面。
(4)具體產品(Concrete Product):這個角色實現了抽象產品角色所定義的介面。某具體產品有專門的具體工廠建立,它們之間往往一一對應。
3 工廠方法模式的通用寫法
以下是工廠方法模式的通用寫法。
public class Client {
public static void main(String[] args) {
IFactory factory = new FactoryA();
factory.makeProduct().doSomething();
factory = new FactoryB();
factory.makeProduct().doSomething();
factory = new FactoryC();
factory.makeProduct().doSomething();
}
//抽象工廠
public interface IFactory {
IProduct makeProduct();
}
//生產ProductA的具體工廠類
static class FactoryA implements IFactory {
public IProduct makeProduct() {
return new ProductA();
}
}
//生產ProductB的具體工廠類
static class FactoryB implements IFactory {
public IProduct makeProduct() {
return new ProductB();
}
}
//生產ProductC的具體工廠類
static class FactoryC implements IFactory {
public IProduct makeProduct() {
return new ProductC();
}
}
//抽象產品
public interface IProduct {
void doSomething();
}
//具體產品:ProductA
static class ProductA implements IProduct {
public void doSomething() {
System.out.println("I am Product A");
}
}
//具體產品:ProductB
static class ProductB extends FactoryB implements IProduct {
public void doSomething() {
System.out.println("I am Product B");
}
}
//具體產品:ProductC
static class ProductC implements IProduct {
public void doSomething() {
System.out.println("I am Product C");
}
}
}
4 使用工廠方法模式實現產品擴充套件
工廠方法模式主要解決產品擴充套件的問題,在簡單工廠中,隨著產品鏈的豐富,如果每個課程的建立邏輯都有區別,則工廠的職責會變得越來越多,有點像萬能工廠,並不便於維護。根據單一職責原則,我們將職能繼續拆分,專人幹專事。Java課程由Java工廠建立,Python課程由Python工廠建立,對工廠本身也做抽象。首先建立ICourseFactory介面。
public interface ICourseFactory {
ICourse create();
}
然後分別建立子工廠,JavaCourseFactory類的程式碼如下。
import com.tom.pattern.factory.ICourse;
import com.tom.pattern.factory.JavaCourse;
public class JavaCourseFactory implements ICourseFactory {
public ICourse create() {
return new JavaCourse();
}
}
PythonCourseFactory類的程式碼如下。
import com.tom.pattern.factory.ICourse;
import com.tom.pattern.factory.PythonCourse;
public class PythonCourseFactory implements ICourseFactory {
public ICourse create() {
return new PythonCourse();
}
}
客戶端測試程式碼如下。
public static void main(String[] args) {
ICourseFactory factory = new PythonCourseFactory();
ICourse course = factory.create();
course.record();
factory = new JavaCourseFactory();
course = factory.create();
course.record();
}
最後看如下圖所示的類圖。
5 工廠方法模式在Logback原始碼中的應用
來看Logback中工廠方法模式的應用,其類圖如下圖所示。
由上圖可以看到,已經分離出不同工廠負責建立不同日誌框架,如Substitute日誌框架、NOP日誌框架、Log4J日誌框架,那麼對應的Logger產品體系也是如此,如下圖所示。
本文為“Tom彈架構”原創,轉載請註明出處。技術在於分享,我分享我快樂!
如果本文對您有幫助,歡迎關注和點贊;如果您有任何建議也可留言評論或私信,您的支援是我堅持創作的動力。關注微信公眾號『 Tom彈架構 』可獲取更多技術乾貨!