全面通透深入剖析工廠方法模式

Tom彈架構發表於2021-11-11

本文節選自《設計模式就該這樣學》

1 工廠方法模式的應用場景

工廠方法模式主要適用於以下應用場景。

(1)建立物件需要大量重複的程式碼。

(2)客戶端(應用層)不依賴產品類例項如何被建立、實現等細節。

(3)一個類通過其子類來指定建立哪個物件。

2 工廠方法模式的UML類圖

工廠方法模式的UML類圖如下圖所示。

file

由上圖可以看到,抽象工廠模式主要包含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();
}

最後看如下圖所示的類圖。

file

5 工廠方法模式在Logback原始碼中的應用

來看Logback中工廠方法模式的應用,其類圖如下圖所示。

file

由上圖可以看到,已經分離出不同工廠負責建立不同日誌框架,如Substitute日誌框架、NOP日誌框架、Log4J日誌框架,那麼對應的Logger產品體系也是如此,如下圖所示。

file

【推薦】Tom彈架構:收藏本文,相當於收藏一本“設計模式”的書

本文為“Tom彈架構”原創,轉載請註明出處。技術在於分享,我分享我快樂!
如果本文對您有幫助,歡迎關注和點贊;如果您有任何建議也可留言評論或私信,您的支援是我堅持創作的動力。關注微信公眾號『 Tom彈架構 』可獲取更多技術乾貨!

相關文章