設計模式-簡單工廠

前言

  你們好我是不同的科技宅,天天進步一點點,體驗生活的美好。java

定義

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

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

場景

  在週一陽光明媚的上午,剛帶上耳機,準備開始一天的工做,老闆忽然來到你身旁。設計模式

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

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

  但是呢沒過多久,總經理也找我說讓我幫他組一臺蘋果電腦,和老闆一樣的套路,我能咋辦,我也很無耐,可是給的預算更低只有4000因而我也只能在原來的基礎上縮減一下配置,勉強達到了要求。測試

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

優勢

  只須要知道產品的名稱便可,就能夠建立你所須要的對象,而無需知道其建立細節。spa

缺點

  工廠類的職責相對太重,增長新的產品須要修改工廠類的判斷邏輯,違背開閉原則,若是產品數量過多,維護將變得很是困難。
  注意:使用反射和枚舉能夠避免頻繁修改工廠類。設計

使用場景

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

小結

  從上面的小故事能夠簡單的理解爲,老闆就是需求方,我就是工廠,老闆只須要告訴他須要什麼就行了,不要管我如何實現,可是若是須要的產品變動了,我就只能作修改來知足要求。3d

UML模型

代碼實例

BaseComputer

public abstract class BaseComputer {

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

}

MacBookPro

public class MacBookPro extends BaseComputer {

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

ThinkPad

public class ThinkPad extends BaseComputer {

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

}

ComputerFactory

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+"電腦。");
        }
    }
}

測試

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();
    }
}

測試結果

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)

重構ComputerFactory - Switch

對於ComputerFactory使用if的寫法不是很優雅,對此咱們能夠改爲使用switch語句。code

注意:Java7之後的版本switch才支持字符串,Java7之前只支持int 、short 、byte 、char
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+"電腦。");
        }
    }
}

重構ComputerFactory - 反射

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;
    }
}

測試類

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();
    }
}

重構ComputerFactory - 反射 + 枚舉

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;
    }
}

電腦枚舉類

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;
    }
}

測試類

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();
        
    }
}

結尾

若是以爲對你有幫助,能夠多多評論,多多點贊哦,也能夠到個人主頁看看,說不定有你喜歡的文章,也能夠隨手點個關注哦,謝謝。

我的銘牌

相關文章
相關標籤/搜索