1. 程式人生 > >設計模式(四)—— 工廠模式

設計模式(四)—— 工廠模式

 

一、含義

工廠模式包含兩個方式:一個是抽象工廠模式,一個是工廠方法模式。

抽象工廠模式:提供一個介面,用於建立相關或依賴物件的家族,而不需要明確指定具體類。

工廠方法模式:定義一個建立物件的介面,但由子類決定要例項化的類是哪一個。工廠方法讓類把例項化推遲到子類中。

二、要點

1.工廠模式都是用來封裝物件的建立。

2.工廠方法使用繼承:把物件的建立委託給子類,子類實現工廠方法來建立物件。

3.抽象工廠使用物件組合:物件的建立被實現在工廠介面所暴露出來的方法中。

4.工廠模式的作用是減少程式和具體類之間的依賴促進鬆耦合。

三、實戰分析工廠模式。

需求:對於一個厭倦了編碼的程式猿來說,回家開個餐廳是個不錯的選擇,賣漢堡就是一個不錯的選擇。

首先就是開一個漢堡店,由於漢堡的種類繁多,在漢堡店的例項中,我就需要更具型別來例項很多不同種類的漢堡,如下所示:

 Hamburg orderHamburg(String type) {
        Hamburg hamburg;
        //例項具體的漢堡工作,隨著漢堡的不同,這裡的程式碼就需要修改
        if (type.equals("beef")) {
            hamburg = new BeefHamburg();
        } else if (type.equals("mutton")) {
            hamburg = new MuttonHamburg();
        } else if (type.equals("bigMAC")) {
            hamburg = new BigMACHamburg();
        }

        //這些步驟是通用的,不需要修改
        hamburg.prepare();
        hamburg.bake();
        hamburg.box();
        return hamburg

    }

所以直接在漢堡店中例項化漢堡,程式的耦合多太高,我們可以把建立漢堡的過程,給他抽離出來,單獨封裝成一個用來建立漢堡的例項類:

public class SimpleHamburgFactory {
    
    public Hamburg createHamburg(String type) {
        Hamburg hamburg;
        if (type.equals("beef")) {
            hamburg = new BeefHamburg();
        } else if (type.equals("mutton")) {
            hamburg = new MuttonHamburg();
        } else if (type.equals("bigMAC")) {
            hamburg = new BigMACHamburg();
        }
        return hamburg;
    }
}

這個時候漢堡店的設計就可如下:

public class HamburgStore {

    //傳遞一個用來例項化漢堡實體的工廠
    SimpleHamburgFactory simpleHamburgFactory;

    public HamburgStore(SimpleHamburgFactory simpleHamburgFactory) {
        this.simpleHamburgFactory = simpleHamburgFactory;
    }

    Hamburg orderHamburg(String type) {
        Hamburg hamburg;
        hamburg = simpleHamburgFactory.createHamburg(type);

        hamburg.prepare();
        hamburg.bake();
        hamburg.box();
        return hamburg

    }
}

在你精心經營下,你的漢堡店越做越大,有很多加盟商想要加盟,加盟商根據所在地點的不同,可能生產的漢堡有所不同,我們的總店就相當於一個超類,別的加盟商就是需要實現這個超類,然後去自定義生產漢堡。總店的設計如下:

public abstract class HamburgStore {


    public Hamburg orderHamburg(String type) {
        hamburg =  createHamburg(type);

        hamburg.prepare();
        hamburg.bake();
        hamburg.box();
        return hamburg;
    }

    //定義一個抽象方法,讓繼承的子類去實現用什麼工廠建立
    abstract Hamburg createHamburg(String type);

}

 所以工廠模式的型別可以如下去理解:

為什麼我們的漢堡可以買的這麼好呢?就是因為我們自己獨特的祕製配料,比如說麵粉,醬料等,隨著加盟商的增多,我們的配料也需要根據地方的不通,就行生產,這是使用我們就需要一個專門製作配料的工廠。

public interface HamburgIngredientFactory {
    
    
    //每個原料都有一個對應的方法建立該原料
    Dough createDough();
    
    Sauce createSauce();
    
    Cheese createCheese();
    
    Pepperoni createPepperoni();
    
    Clams createClam()s;
    
}

然後需要做的事就是為每個區域建造一個工廠,繼承至HamburgIngredientFactory,還需要提供一組原料類,來使用,最後將這些原料整合到HamburgStore中去。

public class SiChuangHamburgIngredientFactory implements HamburgIngredientFactory {

    @Override
    public Dough createDough() {
        return new SiChuanDough();
    }

    @Override
    public Sauce createSauce() {
        return new SiChuanSauce();
    }

    @Override
    public Cheese createCheese() {
        return new SiChuanCheese();
    }

    @Override
    public Pepperoni createPepperoni() {
        return new SiChuanPepperoni();
    }

    @Override
    public Clams createClam() {
        return new SiChuanClams();
    }
}

重新設計漢堡類

public abstract class Hamburg {

    
    String name;

    //這些都是漢堡需要用到的原料
    Dough dough;

    Sauce sauce;

    Pepperoni pepperoni;

    Clams clams;

    //這個準備工作就是收集漢堡所需的原料,這些原料需要用工廠來實現
    abstract void prepare();

    void bake() {
        System.out.println("Bake 20 minutes");
    }

    void box() {
        System.out.println("hamburg put box");
    }

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

    public String getName() {
        return name;
    }
}

設計一個具體的類 :

public class CheeseHamburg extends Hamburg {
    
    //需要一個原料工廠來提供原料
    HamburgIngredientFactory hamburgIngredientFactory;

    public CheeseHamburg(HamburgIngredientFactory hamburgIngredientFactory) {
        this.hamburgIngredientFactory = hamburgIngredientFactory;
    }

    @Override
    void prepare() {
        dough = hamburgIngredientFactory.createDough();
        sauce = hamburgIngredientFactory.createSauce();
        clams = hamburgIngredientFactory.createClam();
    }
}

從上訴程式碼中可以看出,所有抽象工廠的類圖,可以如下圖所示: