設計模式-簡單工廠

設計模式-簡單工廠

前言

  大家好我是不一樣的科技宅,每天進步一點點,體驗不一樣的生活,今天我們聊一聊簡單工廠模式,雖然不在23種設計模式中。但是可以認為是工廠模式的一種特殊實現,並且在日常中使用廣泛,所以還是值得我們去學習的。

定義

  • 簡單工廠模式(Simple Factory Pattern):又稱為靜態工廠方法(Static Factory Method)模式,是一種創建型的設計模式,關注於實例對象創建。
  • 由一個工廠對象通過判斷傳入的參數,決定創建出哪一種產品類的實例,將創建的細節透明化。

  注意:簡單工廠不屬於GOF23種之一。

場景

  在週一陽光明媚的上午,剛帶上耳機,準備開始一天的工作,老闆突然來到你身旁。

  • 老闆: xxx啊,聽說你是學計算機的?
  • 我:是的,學的是軟件工程。
  • 老闆:那幫我組裝一臺蘋果電腦出來吧,週五送到我辦公桌上。
  • 我:內心OS:修電腦,我也就認了,這竟然讓我組裝一臺蘋果電腦,你咋不上天呢?
  • 老闆:預算5000,記得不要超支了。
  • 我:內心雖然波濤洶湧,但是還是說了聲,好的老闆

  於是我就立馬打開chrome,上各大論壇搜索完美黑蘋果配置,在初步確定好配置後,就開始上京東,開始選購CPU,主板,固態,內存,電源等配件。在經歷了兩天的等待,所有配件終於到齊以後,耗費九牛二虎之力,終於在週五前把電腦給組裝好了。

  可是呢沒過多久,總經理也找我說讓我幫他組一臺蘋果電腦,和老闆同樣的套路,我能咋辦,我也很無耐,但是給的預算更低只有

4000於是我也只能在原來的基礎上縮減一下配置,勉強達到了要求。

  我在想要是每個領導都這樣,那我不是得涼涼啊,想到這裡我暗自下定決心,對自己說我下次一定要拒絕他們。

設計模式-簡單工廠

優點

  只需要知道產品的名稱即可,就可以創建你所需要的對象,而無需知道其創建細節。

缺點

  工廠類的職責相對過重,增加新的產品需要修改工廠類的判斷邏輯,違背開閉原則,如果產品數量過多,維護將變得非常困難。   注意:使用反射和枚舉可以避免頻繁修改工廠類。

使用場景

  • 將實例化過程非常複雜的類,通過工廠進行簡化,方便業務方使用。
  • 把創建對象的職責集中管理和控制。

小結

  從上面的小故事可以簡單的理解為:老闆就是需求方,我就是工廠,老闆只需要告訴我,他需要什麼就好了,不管我如何實現。但是如果需要的產品變更了,我就只能做修改來滿足要求。

UML模型

設計模式-簡單工廠

代碼實例

BaseComputer

<code>public abstract class BaseComputer {

    /**
     * 開機
     */
    protected abstract void turnOn();

}/<code>

MacBookPro

<code>public class MacBookPro extends BaseComputer {

    @Override
    protected void turnOn() {

        System.out.println("MacBook Pro 開機了");
    }
}/<code>

ThinkPad

<code>public class ThinkPad extends BaseComputer {

    @Override
    protected void turnOn() {
        System.out.println("Think Pad 開機了");
    }

}/<code>

ComputerFactory

<code>public class ComputerFactory {

    /**
     * 創建電腦
     * @param name 名稱
     * @return 返回電腦
     */
    public static BaseComputer create(String name){
        if("mac".equals(name)){
            return new MacBookPro();
        }else if("thinkPad".equals(name)){
            return new ThinkPad();
        }else {
            throw new IllegalArgumentException("無法創建"+name+"電腦。");
        }
    }
}/<code>

測試

<code>public class Test {

    public static void main(String[] args) {
        BaseComputer mac = ComputerFactory.create("mac");
        mac.turnOn();

        BaseComputer thinkPad = ComputerFactory.create("thinkPad");
        thinkPad.turnOn();

        BaseComputer dell = ComputerFactory.create("dell");
        dell.turnOn();

    }
}/<code>

測試結果

<code>MacBook Pro 開機了

Think Pad 開機了

Exception in thread "main" java.lang.IllegalArgumentException: 無法創建dell電腦。
    at simple.factory.ComputerFactory.create(ComputerFactory.java:22)
    at simple.factory.Test.main(Test.java:18)/<code>

重構ComputerFactory - Switch

對於ComputerFactory使用if的寫法不是很優雅,對此我們可以改成使用switch語句。

注意:Java7以後的版本switch才支持字符串,Java7以前只支持int 、short 、byte 、char

<code>public class ComputerFactory {

    /**
     * 創建電腦
     * @param name 名稱
     * @return 返回電腦
     */
    public static BaseComputer create(String name){
        switch (name){
            case "mac":
                return new MacBookPro();
            case "thinkPad":
                return new ThinkPad();
            default:
                throw new IllegalArgumentException("無法創建"+name+"電腦。");
        }
    }
}/<code>

重構ComputerFactory - 反射

<code>public class ComputerFactory {

    /**
     * 創建電腦
     * @param name 名稱
     * @return 返回電腦
     */
    public static BaseComputer create(String name) {
        BaseComputer computer;
        try {
            computer = (BaseComputer) Class.forName(name).getDeclaredConstructor().newInstance();
        } catch (InstantiationException | IllegalAccessException | ClassNotFoundException | NoSuchMethodException | InvocationTargetException e ) {
            throw new IllegalArgumentException("無法創建"+name+"電腦。");
        }
        return computer;
    }
}/<code>

測試類

<code>public class Test {

    public static void main(String[] args) {
        BaseComputer mac = ComputerFactory.create("simple.factory.MacBookPro");
        mac.turnOn();

        BaseComputer thinkPad = ComputerFactory.create("simple.factory.ThinkPad");
        thinkPad.turnOn();

        BaseComputer dell = ComputerFactory.create("simple.factory.Dell");
        dell.turnOn();
    }
}/<code>

重構ComputerFactory - 反射 + 枚舉

<code>public class ComputerFactory {

    /**
     * 創建電腦
     * @param name 名稱
     * @return 返回電腦
     */
    public static BaseComputer create(ComputerEnum name) {
        BaseComputer computer;
        try {
            computer = (BaseComputer) name.getClazz().newInstance();

        } catch (InstantiationException | IllegalAccessException e ) {
            throw new IllegalArgumentException("無法創建"+name+"電腦。");
        }
        return computer;
    }
}/<code>

電腦枚舉類

<code>public enum ComputerEnum {

    /**
     * 電腦枚舉類
     */

    MAC_BOOK_PRO(MacBookPro.class),

    THINK_PAD(ThinkPad.class),

    ;

    private Class clazz;

    ComputerEnum(Class clazz) {
        this.clazz = clazz;
    }

    public Class getClazz() {
        return clazz;
    }
}/<code>

測試類

<code>public class Test {

    public static void main(String[] args) {
        BaseComputer mac = ComputerFactory.create(ComputerEnum.MAC_BOOK_PRO);
        mac.turnOn();

        BaseComputer thinkPad = ComputerFactory.create(ComputerEnum.THINK_PAD);
        thinkPad.turnOn();

    }
}/<code>

結尾

  如果覺得對你有幫助,可以多多評論,多多點贊哦,也可以到我的主頁看看,說不定有你喜歡的文章,也可以隨手點個關注哦,謝謝。


分享到:


相關文章: