設計模式之工廠模式

工廠模式主要分爲三種:簡單工廠模式、工廠方法模式、抽象工廠模式。


一、簡單工廠模式


模式定義:

簡單工廠模式又稱之爲靜態工廠方法,屬於創建型模式。在簡單工廠模式中,可以根據傳遞的參數不同,返回不同類的實例。簡單工廠模式定義了一個類,這個類專門用於創建其他類的實例,這些被創建的類都有一個共同的父類。


模式結構:


模式實現:

public class SimpleFactory {
    /**
     * 測試類
     */
    @Test
    public void simpleFactoryTest() {
        Computer computer = ComputerFactory.createComputer("microsoft");
        if (null != computer) {
            computer.calculate();
        }
    }
}

/**
 * 抽象產品類
 */
abstract class Computer {
    /**
     * 名稱
     */
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    /**
     * 抽象方法
     */
    abstract void calculate();
}

/**
 * mac
 */
class Mac extends Computer {

    @Override
    void calculate() {
        setName("Mac");
        System.out.println("mac calculate");
    }
}

/**
 * windows
 */
class Microsoft extends Computer {

    @Override
    void calculate() {
        setName("Microsoft");
        System.out.println("windows calculate");
    }
}

/**
 * 電腦工廠
 */
class ComputerFactory {
    /**
     * 根據類型生產產品
     *
     * @param type
     * @return
     */
    public static Computer createComputer(String type) {
        Computer computer = null;
        if ("mac".equals(type)) {
            computer = new Mac();
        } else if ("microsoft".equals(type)) {
            computer = new Microsoft();
        }
        return computer;
    }
}

模式優點:

1、簡單工廠模式實現了對責任的分割,提供了專門的工廠類用於創建對象

2、客戶端無須知道所創建的具體產品類的類名,只需要知道具體產品類所對應的參數即可,對於一些複雜的類名,通過簡單工廠模式可以減少使用者的記憶量

3、通過引入配置文件,可以在不修改任何客戶端代碼的情況下更換和增加新的具體產品類,在一定程度上提高了系統的靈活性


模式缺點:

1、由於工廠類集中了所有產品創建邏輯,一旦不能正常工作,整個系統都要受到影響。

2、使用簡單工廠模式將會增加系統中類的個數,在一定程序上增加了系統的複雜度和理解難度

3、系統擴展困難,一旦添加新產品就不得不修改工廠邏輯,在產品類型較多時,有可能造成工廠邏輯過於複雜,不利於系統的擴展和維護


使用場景:

1、工廠類負責創建的對象比較少

2、客戶端只知道傳入工廠類的參數,對於如何創建對象不關心



二、工廠方法模式


模式定義:

工廠方法模式定義了一個創建對象的接口,但由子類決定要實例化的類是哪一個。工廠方法模式讓實例化推遲到子類


模式結構:


模式實現:

public class SimpleFactory {
    /**
     * 測試類
     */
    @Test
    public void factoryMethodTest() {
        ComputerFactory factory = new MacFactory();
        //如需更改,只需增加一行代碼即可
        factory = new MicrosoftFactory();
        Computer computer = factory.createComputer();
        if (null != computer) {
            computer.calculate();
        }
    }
}

/**
 * 抽象產品類
 */
abstract class Computer {
    /**
     * 名稱
     */
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    /**
     * 抽象方法
     */
    abstract void calculate();
}

/**
 * mac
 */
class Mac extends Computer {

    @Override
    void calculate() {
        setName("Mac");
        System.out.println("mac calculate");
    }
}

/**
 * windows
 */
class Microsoft extends Computer {

    @Override
    void calculate() {
        setName("Microsoft");
        System.out.println("windows calculate");
    }
}

/**
 * 抽象工廠
 */
abstract class ComputerFactory {
    public abstract Computer createComputer();
}

/**
 * mac電腦製造工廠
 */
class MacFactory extends ComputerFactory {

    @Override
    public Computer createComputer() {
        return new Mac();
    }
}

/**
 * windows電腦製造工廠
 */
class MicrosoftFactory extends ComputerFactory {

    @Override
    public Computer createComputer() {
        return new Microsoft();
    }
}



模式優點:

1、在工廠方法中,用戶只需要知道所要產品的具體工廠,無須關係具體的創建過程,甚至不需要具體產品類的類名

2、在系統增加新的產品時,我們只需要添加一個具體產品類和對應的實現工廠,無需對原工廠進行任何修改,很好地符合了“開閉原則”


模式缺點:

1、每次增加一個產品時,都需要增加一個具體類和對象實現工廠,是的系統中類的個數成倍增加,在一定程度上增加了系統的複雜度,同時也增加了系統具體類的依賴。這並不是什麼好事


使用場景:

1、一個類不知道它所需要的對象的類。在工廠方法模式中,我們不需要具體產品的類名,我們只需要知道創建它的具體工廠即可

2、將創建對象的任務委託給多個工廠子類中的某一個,客戶端在使用時可以無須關心是哪一個工廠子類創建產品子類,需要時再動態指定


三、抽象工廠模式


模式定義:

抽象工廠模式提供一個接口,用於創建相關或者依賴對象的家族,而不需要明確指定具體類。

 在講解抽象工廠模式之前,我們需要理解兩個概念:

        產品等級結構。產品的等級結構也就是產品的繼承結構。例如一個爲空調的抽象類,它有海爾空調、格力空調、美的空調等一系列的子類,那麼這個抽象類空調和他的子類就構成了一個產品等級結構。

        產品族。產品族是在抽象工廠模式中的。在抽象工廠模式中,產品族是指由同一個工廠生產的,位於不同產品等級結構中的一組產品。比如,海爾工廠生產海爾空調。海爾冰箱,那麼海爾空調則位於空調產品族中。


模式結構:


模式實現:

public class SimpleFactory {
    /**
     * 測試類
     */
    @Test
    public void abstractFactoryTest() {
        ComputerFactory factory = new MacFactory();
        //如需更改,只需增加一行代碼即可
        factory = new MicrosoftFactory();
        Computer computer = factory.createComputer();
        Earphone earphone = factory.createEarphone();
        computer.calculate();
        earphone.listenMusic();
    }
}

/**
 * 抽象電腦類
 */
abstract class Computer {
    /**
     * 名稱
     */
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    /**
     * 抽象方法
     */
    abstract void calculate();
}

/**
 * mac
 */
class Mac extends Computer {

    @Override
    void calculate() {
        setName("Mac");
        System.out.println("mac calculate");
    }
}

/**
 * windows
 */
class Microsoft extends Computer {

    @Override
    void calculate() {
        setName("Microsoft");
        System.out.println("windows calculate");
    }
}

/**
 * 抽象耳機類
 */
abstract class Earphone {
    /**
     * 抽象方法
     */
    abstract void listenMusic();
}

/**
 * mac耳機
 */
class MacEarphone extends Earphone {

    @Override
    void listenMusic() {
        System.out.println("mac listen music");
    }
}

/**
 * windows耳機
 */
class MicroEarphone extends Earphone {

    @Override
    void listenMusic() {
        System.out.println("windows listen music");
    }
}

/**
 * 抽象工廠
 */
abstract class ComputerFactory {
    public abstract Computer createComputer();

    public abstract Earphone createEarphone();
}

/**
 * mac電腦製造工廠
 */
class MacFactory extends ComputerFactory {

    @Override
    public Computer createComputer() {
        return new Mac();
    }

    @Override
    public Earphone createEarphone() {
        return new MacEarphone();
    }
}

/**
 * windows電腦製造工廠
 */
class MicrosoftFactory extends ComputerFactory {

    @Override
    public Computer createComputer() {
        return new Microsoft();
    }

    @Override
    public Earphone createEarphone() {
        return new MicroEarphone();
    }
}


模式優點:

1、抽象工廠隔離了具體類的生成,是的客戶端不需要知道什麼被創建。所有的具體工廠都實現了抽象工廠中定義的公共接口,因此只需要改變具體工廠的實例,就可以在某種程度上改變整個軟件系統的行爲

2、當一個產品族中的多個對象被設計成一起工作時,它能夠保證客戶端始終只使用同一個產品族中的對象


模式缺點:

1、添加新的行爲時比較麻煩。如果需要添加一個新產品族對象時,需要更改接口及其下所有子類,這必然會帶來很大的麻煩


使用場景:

1、系統中有多於一個的產品族,而每次只使用其中某一產品族

2、屬於同一個產品族的產品將在一起使用,這一約束必須在系統的設計中體現出來

3、系統提供一個產品類的庫,所有的產品以同樣的接口出現,從而使客戶端不依賴於具體實現


總結:

簡單工廠模式:

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

2、簡單工廠模式最大的優點在於實現對象的創建和對象的使用分離,但是如果產品過多時,會導致工廠代碼非常複雜


工廠方法模式:

1、工廠方法模式完全符合“開閉原則”

2、工廠方法允許類將實例化延伸到子類進行

3、工廠方法讓子類決定要實例化的類時哪一個。在這裏我們要明白這並不是工廠來決定生成哪種產品,而是在編寫創建者類時,不需要知道實際創建的產品是哪個,選擇了使用哪個子類,就已經決定了實際創建的產品時哪個了


抽象工廠模式:

1、 抽象工廠模式中主要的優點在於具體類的隔離,是的客戶端不需要知道什麼被創建了。其缺點在於增加新的等級產品結構比較複雜,需要修改接口及其所有子類



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章