Java設計模式之工廠模式詳解

簡單工廠其實並非設計模式,只是一種編程習慣。

首先咱們建立父類Cup,全部杯子類的父類。再建立它的子類BigCup和SmallCup類。編程

public abstract class Cup {
    public abstract void use();
}

public class BigCup extends Cup {
    @Override
    public void use() {
        System.out.println("大杯裝500ml水");
    }
}

public class SmallCup extends Cup {
    @Override
    public void use() {
        System.out.println("小杯裝100ml水");
    }
}

而後咱們建立工廠類CupFactory,工廠裏聲明瞭Cup引用,根據傳入的參數type來判斷生產什麼類型的杯子,這樣外部只須要傳入類型就能夠生成想要的類型的對象,如今運行看一下結果,沒有問題。設計模式

public class CupFactory{
    public Cup makeCup(String type){
        Cup cup = null;
        if (type.equals("big")){
            cup = new BigCup();
        }else if (type.equals("small")){
            cup = new SmallCup();
        }
        return cup;
    }
}

public static void main(String[] args){
    CupFactory cupFactory = new CupFactory();
    Cup smallCup = cupFactory.makeCup("small");
    smallCup.use();
    Cup bigCup = cupFactory.makeCup("big");
    bigCup.use();
}

結果:
小杯裝100ml水
大杯裝500ml水ide


簡單工廠雖然解決了一些問題可是當咱們的須要增長子類的時候就很麻煩了,須要修改工廠類裏的代碼,違反了開放封閉原則,因此咱們如今使用真正的工廠模式來解決這個問題。測試


工廠模式,又稱爲工廠方法模式。定義了一個建立產品對象的工廠接口,將實際建立工做推遲到子類工廠當中。

首先咱們建立抽象類Tableware,表明全部餐具的父類,再建立一個抽象工廠類TablewareFactory,抽象工廠裏面有抽象方法makeTableware來製造餐具。而後咱們建立4個餐具子類,分別是BigBowl、SmallBowl、BigCuphe和SmallCup。設計

public abstract class Tableware {
    public abstract void use();
}

public abstract class TableWareFactory {
    public abstract Tableware makeTableware(String type);
}

public class BigBowl extends Tableware {
    @Override
    public void use() {
        System.out.println("大碗裝500g飯");
    }
}

public class SmallBowl extends Tableware {
    @Override
    public void use() {
        System.out.println("小碗裝100g飯");
    }
}

public class BigCup extends Tableware {
    @Override
    public void use() {
        System.out.println("大杯裝500ml水");
    }
}

public class SmallCup extends Tableware {
    @Override
    public void use() {
        System.out.println("小杯裝100ml水");
    }
}

接下來咱們須要實現工廠類了,這是最關鍵的部分,從上述4個子類能夠看出,BigBowl和SmallBowl是一類產品,而BigCup和SamllCup是另外一類,因此咱們建立兩個子類工廠,分別是BowlFactory和CupFactory。它們生產不一樣的產品,可是又能根據參數來生產不一樣規格的同類產品。在子類工廠中的makeTableware方法纔是決定生產什麼產品,而父類工廠並不知道,這就是將實際建立工做推遲到子類工廠當中。當咱們想要新建別的產品的時候增長新的子類工廠便可。code

public class BowlFactory extends TableWareFactory {

    @Override
    public Tableware makeTableware(String type) {
        Tableware tableware = null;
        if (type.equals("big")){
            tableware = new BigBowl();
        }else if (type.equals("small")){
            tableware = new SmallBowl();
        }
        return tableware;
    }
}

public class CupFactory extends TableWareFactory {
    @Override
    public Tableware makeTableware(String type) {
        Tableware tableware = null;
        if (type.equals("big")){
            tableware = new BigCup();
        }else if (type.equals("small")){
            tableware = new SmallCup();
        }
        return tableware;
    }
}

測試一下看看結果,結果沒有問題。對象

TableWareFactory cupFactory = new CupFactory();
Tableware bigCup = cupFactory.makeTableware("big");
bigCup.use();
Tableware smallCup = cupFactory.makeTableware("small");
smallCup.use();
TableWareFactory bowlFactory = new BowlFactory();
Tableware bigBowl =  bowlFactory.makeTableware("big");
bigBowl.use();
Tableware smallBowl = bowlFactory.makeTableware("small");
smallBowl.use();

結果:
大杯裝500ml水
小杯裝100ml水
大碗裝500g飯
小碗裝100g飯接口


抽象工廠模式實際上是在工廠方法模式的基礎上加入了產品族的概念,也就是工廠裏會生產多種產品,他們須要配套使用,例如衣服和褲子。

咱們先建立一個抽象工廠BaseFactory類,有兩個抽象方法makeTableware和getFood,分別生產餐具和食物,由於它們兩個是要配合使用的。get

public abstract class BaseFactory {
    public abstract Tableware makeTableware();
    public abstract  Food getFood();
}

而後咱們建立餐具的抽象父類Tableware和事物的抽象父類Food,再建立它們的子類BigBowl、SmallCup、Meat和Milk類。產品

public abstract class Tableware {
    public abstract void use();
}

public abstract class Food {
    public abstract void name();
}

public class BigBowl extends Tableware {
    @Override
    public void use() {
        System.out.println("500ml的大碗");
    }
}

public class SmallCup extends Tableware {
    @Override
    public void use() {
        System.out.println("100ml的小杯子");
    }
}

public class Meat extends Food {
    @Override
    public void name() {
        System.out.println("肉");
    }
}

public class Milk extends Food {
    @Override
    public void name() {
        System.out.println("牛奶");
    }
}

接下來咱們建立兩個子類工廠MeatWithBowlFactory和MilkWithCupFactory
類,這兩個類把肉和碗分到一個工廠裏,牛奶和杯子分到一個工廠裏,表示他們須要配套使用。這裏的makeTableware和getFood方法也能夠像上面工廠方法模式裏同樣接受參數生成不一樣規格的產品,如今是直接返回一個對象。

public class MeatWithBowlFactory extends BaseFactory {
    @Override
    public Tableware makeTableware() {
        return new BigBowl();
    }

    @Override
    public Food getFood() {
        return new Meat();
    }
}

public class MilkWithCupFactory extends BaseFactory{
    @Override
    public Tableware makeTableware() {
        return new SmallCup();
    }

    @Override
    public Food getFood() {
        return new Milk();
    }
}

如今測試一下結果,沒有問題,同一個工廠能夠生產須要配套的產品。

BaseFactory baseFactory;
   baseFactory = new MeatWithBowlFactory();
   BigBowl bigBowl = (BigBowl) baseFactory.makeTableware();
   bigBowl.use();
   Meat meat = (Meat)baseFactory.getFood();
   meat.name();

   baseFactory = new MilkWithCupFactory();
   SmallCup smallCup = (SmallCup) baseFactory.makeTableware();
   smallCup.use();
   Milk milk = (Milk)baseFactory.getFood();
   milk.name();

結果:
500ml的大碗

100ml的小杯子
牛奶


總結:

  • 簡單工廠模式其實只是把建立對象這個經常使用的工廠作成工廠類方便調用,可是修改的時候須要修改工廠的代碼,只是一種編程習慣,不是設計模式。
  • 工廠模式,也就是工廠方法模式是解決了簡單工廠要修改代碼的問題,他把對象的建立操做延遲到子類工廠中,這樣新增產品就不須要修改代碼。
  • 抽象工廠模式就是在工廠方法模式的基礎上加入了產品族的概念,若是幾個產品須要配套使用,就能夠將他們放在同一個工廠裏自行選擇搭配,好比牛肉放在瓷碗裏,豬肉放在鐵碗裏。
相關文章
相關標籤/搜索