java設計模式-簡單工廠模式

燕雀安知毛驢之志發表於2020-12-22

簡單工廠模式詳解

1,概述

  簡單工廠模式屬於建立型模式又叫做靜態工廠方法模式,它屬於類建立型模式。在簡單工廠模式中,可以根據引數的不同返回不同類的例項。

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

  簡單工廠只需要傳入一個正確的引數,就可以獲取所需要的物件,而無需知道其實現過程。

  簡單工廠模式中用於被建立例項的方法通常為靜態(static)方法,因此簡單工廠模式又被成為靜態工廠方法(Static Factory Method)。

  下面由我深入淺出的給大家講解下簡單工廠模式,不足之處還望批評指正

2,結構圖

 

  

  • Factory:工廠類,簡單工廠模式的核心,它負責實現建立所有例項的內部邏輯。工廠類的建立產品類的方法可以被外界直接呼叫,建立所需的產品物件。
  • IProduct:抽象產品類,簡單工廠模式所建立的所有物件的父類,它負責描述所有例項所共有的公共介面。
  • Product:具體產品類,是簡單工廠模式的建立目標

 

 

 3,簡單工廠舉例說明 

  這裡我們以食品加工廠來舉例,假設有一個食品加工廠,主要加工啤酒飲料礦泉水,根據需求,我們就需要用一個單獨的類來專門生產啤酒飲料礦泉水,這就用到了簡單工廠模式,下面我們來實現簡單工廠模式。

 4,具體程式碼實現

  第一步:我們首先建立我們的食品基類,也就是食品父類,也就是我們結構圖中抽象產品類,這是個抽象類。

package pattern.simplenessfactory;

/**
 *產品抽象類
 * @author ningbeibei
 *
 */
public abstract class Product {
    //獲取產品方法
    public abstract void getFood();
}

  第二步:具體的啤酒飲料礦泉水食品類都需要繼承食品抽象類 Product

package pattern.simplenessfactory;

/**
 * 具體啤酒類繼承自Product類
 * @author ningbeibei
 *
 */
public class Berr extends Product {

    @Override
    public void getFood() {
        System.out.println("啤酒");
    };
}
package pattern.simplenessfactory;

/**
 * 具體飲料類繼承自Product
 * @author ningbeibei
 *
 */
public class Drinks extends Product {

    @Override
    public void getFood() {
        System.out.println("飲料");
    }

}
package pattern.simplenessfactory;

/**
 * 具體礦泉水類繼承自Product
 * @author ningbeibei
 *
 */
public class Water extends Product {

    @Override
    public void getFood() {
        System.out.println("礦泉水");
    }


}

  第三步:上面我們已經把產品類設計好了,現在開始建立食品加工廠Factory

  食品加工工廠專門負責建立具體的食品物件並返回大家看下面getCommodity(String type) 方法,這個方法是靜態方法,並且根據引數決定建立食品物件,方法內部通過邏輯判斷決定返回啤酒還是飲料或者是礦泉水,要注意的是:Product product = null; 這個變數用到的是java的特性繼承和多型,簡單說:子類物件父型別。

package pattern.simplenessfactory;
/**
 * 食品加工工廠
 * 根據需要專門負責生產各中食品,也就是專門建立各種所需物件
 * @author ningbeibei
 */
public class Factory {
    //根據傳入引數返某個食品,也就是食品物件
    public static Product getCommodity(String type) {
        //這個變數是抽象類,也就是食品類的父類
        Product product = null;    
        switch (type) {
        case "啤酒":
            product = new Berr();
            break;
        case "飲料":
            product = new Drinks();
            break;
        case "礦泉水":
            product = new Water();
            break;
        }
        return product;
    }
}

  第四步:編寫測試類

package pattern.simplenessfactory;

/**
 * 簡單工廠模式測試類
 * @author ningbeibei
 */
public class test {

    public static void main(String[] args) {
        //通過工廠Factory類中的getCommodity()方法獲取啤酒物件
        Factory.getCommodity("啤酒").getFood();
        //通過工廠Factory類中的getCommodity()方法獲取飲料物件
        Factory.getCommodity("飲料").getFood();
        //通過工廠Factory類中的getCommodity()方法獲取礦泉水物件
        Factory.getCommodity("礦泉水").getFood();
    }
}

6,思考題

  現在我們來思考一個問題,如果我這個工廠隨著規模擴大業務提升,我現在不但要賣啤酒飲料礦泉水,我還要賣花生牛奶八寶粥,請問在現有簡單工廠模式下怎麼擴充套件新產品?

7,思考題解答

  如果簡單工廠要擴充套件新產品那麼需要以下幾步

  (1),新增產品類並繼承Product類    

package pattern.simplenessfactory;

/**
 * 新增產品花生,繼承自Product類
 * @author ningbeibei
 *
 */
public class Peanut extends Product {
    
    @Override
    public void getFood() {
        System.out.println("新增產品花生");
    }

}

  (2),修改食品工廠Factory類中的邏輯判斷,新增新增產品花生邏輯判斷

package pattern.simplenessfactory;
/**
 * 食品加工工廠
 * 根據需要專門負責生產各中食品,也就是專門建立各種所需物件
 * @author ningbeibei
 */
public class Factory {
    //根據傳入引數返某個食品,也就是食品物件
    public static Product getCommodity(String type) {
        //這個變數是抽象類,也就是食品類的父類
        Product product = null;
        switch (type) {
        case "啤酒":
            product = new Berr();
            break;
        case "飲料":
            product = new Drinks();
            break;
        case "礦泉水":
            product = new Water();
            break;
        case "花生":
            product = new Peanut();
            break;
        }
        return product;
    }
}

  現在我們發現我們竟然修改了食品工廠邏輯程式碼,這對於一個大型專案來說,是有風險的,並且違背了設計模式開閉原則:簡單說明開閉原則,就是對擴充套件開放對修改封閉

  測試類

package pattern.simplenessfactory;

/**
 * 簡單工廠模式測試類
 * @author ningbeibei
 */
public class test {

    public static void main(String[] args) {
        //通過工廠Factory類中的getCommodity()方法獲取啤酒物件
        Factory.getCommodity("啤酒").getFood();
        //通過工廠Factory類中的getCommodity()方法獲取飲料物件
        Factory.getCommodity("飲料").getFood();
        //通過工廠Factory類中的getCommodity()方法獲取礦泉水物件
        Factory.getCommodity("礦泉水").getFood();
        //新增花生產品,通過工廠Factory類中的getCommodity()方法獲取花生物件
        Factory.getCommodity("花生").getFood();
    }
}

  執行結果

8,現在我們總結下簡單工廠模式的優缺店

  優點:

  • 工廠類含有必要的判斷邏輯,可以決定在什麼時候建立哪一個產品類的例項,客戶端可以免除直接建立產品物件的責任,而僅僅“消費”產品;簡單工廠模式通過這種做法實現了對責任的分割,它提供了專門的工廠類用於建立物件
  • 客戶端無須知道所建立的具體產品類的類名,只需要知道具體產品類所對應的引數即可,對於一些複雜的類名,通過簡單工廠模式可以減少使用者的記憶量。
  • 通過引入配置檔案,可以在不修改任何客戶端程式碼的情況下更換和增加新的具體產品類,在一定程度上提高了系統的靈活性。

  缺點:

  • 由於工廠類集中了所有產品建立邏輯,一旦不能正常工作,整個系統都要受到影響。
  • 使用簡單工廠模式將會增加系統中類的個數,在一定程式上增加了系統的複雜度和理解難度。
  • 系統擴充套件困難,一旦新增新產品就不得不修改工廠邏輯,同樣破壞了“開閉原則”;在產品型別較多時,有可能造成工廠邏輯過於複雜,不利於系統的擴充套件和維護
  • 簡單工廠模式由於使用了靜態工廠方法,造成工廠角色無法形成基於繼承的等級結構

9,java工廠模式學習思路

  簡單工廠模式===》而後工廠模式====》最後抽象工廠模式

  學習就像打野要先打野區怪伺機偷小龍,最後搞大龍

  由淺入深的學習在才能理解的更深更全面而後方能融會貫通

  寫的不足之處望批評指正,我一定改

 

相關文章