深入理解Java設計模式之簡單工廠模式

一、什麼是簡單工廠模式

簡單工廠模式又稱為靜態工廠模式,實質是由一個工廠類根據傳入的參數,動態決定應該創建哪一個產品類(這些產品類繼承自一個父類或接口)的實例。簡單工廠模式的創建目標,所有創建的對象都是充當這個角色的某個具體類的實例。

其實就是將一個具體類的實例化交給一個靜態工廠方法來執行,它不屬於GOF的23種設計模式,但現實中卻經常會用到,而且思想也非常簡單。

二、簡單工廠模式的結構

簡單工廠模式包含如下角色:

Factory:工廠角色

Product:抽象產品角色

ConcreteProduct:具體產品角色

工廠角色(Creator) 是簡單工廠模式的核心,它負責實現創建所有具體產品類的實例。工廠類可以被外界直接調用,創建所需的產品對象。
抽象產品角色(Product) 是所有具體產品角色的父類,它負責描述所有實例所共有的公共接口。
具體產品角色(Concrete Product) 繼承自抽象產品角色,一般為多個,是簡單工廠模式的創建目標。工廠類返回的都是該角色的某一具體產品。

三、簡單工廠模式的應用場景

1.前幾天蘋果公司剛發佈IPhone Xs和iPhone XR,那麼問題來瞭,蘋果公司的代工廠到底生產多少種尺寸的手機呢?

1.由工廠決定生產哪種型號的的手機,蘋果公司的工廠就是一個工廠類,是簡單工廠模式的核心類。

2.iPhoneX、iPhoneXs、iphoneXr都是蘋果手機,隻是型號不同。蘋果手機類滿足抽象的定義,各個型號的手機類是其具體實現。

2.考慮一個簡單的軟件應用場景,一個軟件系統可以提供多個外觀不同的按鈕(如圓形按鈕、矩形按鈕、菱形按鈕等),這些按鈕都源自同一個基類,不過在繼承基類後不同的子類修改瞭部分屬性從而使得它們可以呈現不同的外觀,如果我們希望在使用這些按鈕時,不需要知道這些具體按鈕類的名字,隻需要知道表示該按鈕類的一個參數,並提供一個調用方便的方法,把該參數傳入方法即可返回一個相應的按鈕對象,此時,就可以使用簡單工廠模式。

在以下情況下可以使用簡單工廠模式:

工廠類負責創建的對象比較少:由於創建的對象較少,不會造成工廠方法中的業務邏輯太過復雜。
客戶端隻知道傳入工廠類的參數,對於如何創建對象不關心:客戶端既不需要關心創建細節,甚至連類名都不需要記住,隻需要知道類型所對應的參數。

四、簡單工廠模式和工廠方法模式區別

簡單工廠模式:

(1)工廠類負責創建的對象比較少,由於創建的對象較少,不會造成工廠方法中的業務邏輯太過復雜。

(2)客戶端隻知道傳入工廠類的參數,對於如何創建對象並不關心。

工廠方法模式:

(1)客戶端不知道它所需要的對象的類。

(2)抽象工廠類通過其子類來指定創建哪個對象。

五、簡單工廠模式和策略模式的異同

策略模式和簡單工廠模式看起來非常相似,都是通過多態來實現不同子類的選取,這種思想應該是從程序的整體來看得出的。

如果從使用這兩種模式的角度來看的話,我們會發現在簡單工廠模式中我們隻需要傳遞相應的條件就能得到想要的一個對象,然後通過這個對象實現算法的操作。

而策略模式,使用時必須首先創建一個想使用的類對象,然後將該對象最為參數傳遞進去,通過該對象調用不同的算法。

在簡單工廠模式中實現瞭通過條件選取一個類去實例化對象,策略模式則將選取相應對象的工作交給模式的使用者,它本身不去做選取工作。

結合下面的代碼和下面的釋義不難看出,其實兩個的差別很微妙,Factory是直接創建具體的對象並用該對象去執行相應的動作,而Context將這個操作給瞭Context類,沒有創建具體的對象,實現的代碼的進一步封裝,客戶端代碼並不需要知道具體的實現過程。

六、簡單工廠模式的優缺點

優點:

工廠類是整個模式的關鍵.包含瞭必要的邏輯判斷,根據外界給定的信息,決定究竟應該創建哪個具體類的對象.

通過使用工廠類,外界可以從直接創建具體產品對象的尷尬局面擺脫出來,僅僅需要負責“消費”對象就可以瞭。

而不必管這些對象究竟如何創建及如何組織的.明確瞭各自的職責和權利,有利於整個軟件體系結構的優化。

缺點:

由於工廠類集中瞭所有實例的創建邏輯,違反瞭開閉原則,將全部創建邏輯集中到瞭一個工廠類中;

它所能創建的類隻能是事先考慮到的,如果需要添加新的類,則就需要改變工廠類瞭。

當系統中的具體產品類不斷增多時候,可能會出現要求工廠類根據不同條件創建不同實例的需求.

這種對條件的判斷和對具體產品類型的判斷交錯在一起,很難避免模塊功能的蔓延,對系統的維護和擴展非常不利;

開閉原則定義:一個軟件實體如類、模塊和函數應該對擴展開放,對修改關閉。

開放-封閉原則的意思就是說,你設計的時候,時刻要考慮,盡量讓這個類是足夠好,寫好瞭就不要去修改瞭,如果新需求來,我們增加一些類就完事瞭,原來的代碼能不動則不動。這個原則有兩個特性,一個是說“對於擴展是開放的”,另一個是說“對於更改是封閉的”。面對需求,對程序的改動是通過增加新代碼進行的,而不是更改現有的代碼。這就是“開放-封閉原則”的精神所在。

七、簡單工廠模式的實現

首先創建一個”蘋果手機”類,定義一個獲取手機尺寸的方法

//蘋果手機
public abstract class ApplePhone {
    //獲取尺寸
    protected abstract void getSize();
 }

蘋果手機不同型號的”手機類”。

public class IphoneX:ApplePhone{
    public void getSize() {
        Console.WriteLine("iPhoneX屏幕:3.5英寸");
    }
}
public class IphoneXs:ApplePhone{
     public void getSize() {
        Console.WriteLine("iPhoneX屏幕:4.5英寸");
    }
}
public class IphoneXR:ApplePhone{
    public void getSize() {
        Console.WriteLine("iPhoneX屏幕:5.5英寸");
    }
}

建立一個”工廠類”生產不同型號的”手機對象”。

//蘋果工廠
public class AppleFactory {
    public static ApplePhone createPhone(String model){
        ApplePhone applePhone = null;
        switch (model) {
            case"iPhoneX":
                applePhone = new IphoneX();
                break;
            case"iPhoneXs":
                applePhone = new IphoneXs();
                break;
            case"iPhoneXr":
                applePhone = new IphoneXR();
                break;
            default:
                break;
        }
        returnapplePhone;
    }
}

最後是客戶端測試類

public class Client {
    public static void main(String[] args) {
        ApplePhone applePhone ;
        applePhone = AppleFactory.createPhone("iPhoneX");
        applePhone.getSize();
        applePhone = AppleFactory.createPhone("iPhoneXs");
        applePhone.getSize();
        applePhone = AppleFactory.createPhone("iPhoneXr");
        applePhone.getSize();
    }
}

八、總結

創建型模式對類的實例化過程進行瞭抽象,能夠將對象的創建與對象的使用過程分離。

簡單工廠模式又稱為靜態工廠方法模式,它屬於類創建型模式。在簡單工廠模式中,可以根據參數的不同返回不同類的實例。

簡單工廠模式專門定義一個類來負責創建其他類的實例,被創建的實例通常都具有共同的父類。

簡單工廠模式包含三個角色:工廠角色負責實現創建所有實例的內部邏輯;抽象產品角色是所創建的所有對象的父類,負責描述所有實例所共有的公共接口;具體產品角色是創建目標,所有創建的對象都充當這個角色的某個具體類的實例。

簡單工廠模式的要點在於:當你需要什麼,隻需要傳入一個正確的參數,就可以獲取你所需要的對象,而無須知道其創建細節。

簡單工廠模式最大的優點在於實現對象的創建和對象的使用分離,將對象的創建交給專門的工廠類負責,但是其最大的缺點在於工廠類不夠靈活,增加新的具體產品需要修改工廠類的判斷邏輯代碼,而且產品較多時,工廠方法代碼將會非常復雜。

簡單工廠模式適用情況包括:工廠類負責創建的對象比較少;客戶端隻知道傳入工廠類的參數,對於如何創建對象不關心。

本篇文章就到這裡瞭,希望能夠給你帶來幫助,也希望您能夠多多關註WalkonNet的更多內容!

推薦閱讀: