1. 程式人生 > 實用技巧 >設計模式之抽象工廠模式

設計模式之抽象工廠模式

設計模式之抽象工廠模式

基本介紹

  • 抽象工廠模式:定義了一個interface用於建立相關或有依賴關係的物件簇,而無需指明具體的類。
  • 抽象工廠模式將簡單工廠模式和工廠方法模式進行整合
  • 從設計層面看,抽象工廠模式就是對簡單工廠模式的改進(或者成為進一步的抽象)
  • 將工廠抽象成兩層,AbsFactory(抽象工廠)和具體實現的工廠子類。程式設計師可以根據建立物件型別使用對應的工廠子類。這樣將單個的簡單工廠類變成了工廠簇,更利於程式碼的維護和拓展。

模式結構

工廠方法模式由抽象工廠、具體工廠、抽象產品和具體產品等4個要素構成。

  1. 抽象工廠(Abstract Factory):提供了建立產品的介面,呼叫者通過它訪問具體工廠的工廠方法 newProduct() 來建立產品。

  2. 具體工廠(ConcreteFactory):主要是實現抽象工廠中的抽象方法,完成具體產品的建立。

  3. 抽象產品(Product):定義了產品的規範,描述了產品的主要特性和功能。

  4. 具體產品(ConcreteProduct):實現了抽象產品角色所定義的介面,由具體工廠來建立,它同具體工廠之間一一對應。

具體實現

我們用抽象工廠模式來完成之前的披薩專案

1.繪製UML類圖

2.編寫程式碼

/**
 * @author gaoteng
 * 將Pizza類做成抽象(抽象產品)
 */
public abstract class Pizza {
    public String getName() {
        return name;
    }

    /**
     * 名字
     */
    protected String name;
    /**
     *準備原材料, 不同的披薩不一樣,因此,我們做成抽象方法
     */
    public abstract void prepare();
    /**
     * 烘烤
     */
    public void bake() {
        System.out.println(name + " baking;");
    }

    /**
     * 切片
     */
    public void cut() {
        System.out.println(name + " cutting;");
    }
    /**
     * 打包
     */
    public void box() {
        System.out.println(name + " boxing;");
    }

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


/**
 * @author gaoteng
 * 一個抽象工廠模式的抽象層(抽象工廠)
 */
public interface AbsFactory {
    /**
     * 讓下面的子類去實現具體方法
     * @param orderType 訂單型別
     * @return
     */
    Pizza createPizza(String orderType);
}



/**
 * @author gaoteng
 * 具體工廠子類(具體工廠)
 */
public class BJFactory implements AbsFactory {
    @Override
    public Pizza createPizza(String orderType) {
        System.out.println("使用的是抽象工廠模式");
        Pizza pizza = null;
        if("cheese".equals(orderType)){
            pizza = new BJCheesePizza();
            pizza.setName("北京乳酪披薩");
        }else if(orderType.equals("pepper")){
            pizza = new BJPepperPizza();
            pizza.setName("北京胡椒披薩");
        }
        return pizza;
    }
}


/**
 * @author gaoteng
 * 具體工廠子類(具體工廠)
 */
public class LDFactory implements AbsFactory {

    @Override
    public Pizza createPizza(String orderType) {
        System.out.println("使用的是抽象工廠模式");
        Pizza pizza =null;
        if(orderType.equals("cheese")){
            pizza = new LDCheesePizza();
            pizza.setName("倫敦乳酪披薩");
        }else if(orderType.equals("pepper")){
            pizza = new LDPepperPizza();
            pizza.setName("倫敦胡椒披薩");
        }
        return null;
    }
}

//具體產品
public class BJCheesePizza extends Pizza {
    @Override
    public void prepare() {
        setName("北京的乳酪pizza");
        System.out.println(" 北京的乳酪pizza 準備原材料");
    }
}
public class BJPepperPizza extends Pizza {
    @Override
    public void prepare() {
        setName("北京的胡椒pizza");
        System.out.println(" 北京的胡椒pizza 準備原材料");
    }
}
public class LDCheesePizza extends Pizza {
    @Override
    public void prepare() {
        setName("倫敦的乳酪pizza");
        System.out.println(" 倫敦的乳酪pizza 準備原材料");
    }
}
public class LDPepperPizza extends Pizza {
    @Override
    public void prepare() {
        setName("倫敦的胡椒pizza");
        System.out.println(" 倫敦的胡椒pizza 準備原材料");
    }
}

3.測試

public class TestAbstractFactory {
    public static void main(String[] args) {
        OrderPizza orderPizza = new OrderPizza(new BJFactory());
        Pizza pizza = orderPizza.factory.createPizza("cheese");
        System.out.println(pizza.getName());
    }
}

優缺點

優點:

  • 可以在類的內部對產品族中相關聯的多等級產品共同管理,而不必專門引入多個新的類來進行管理。
  • 當需要產品族時,抽象工廠可以保證客戶端始終只使用同一個產品的產品組。
  • 抽象工廠增強了程式的可擴充套件性,當增加一個新的產品族時,不需要修改原始碼,滿足開閉原則。

缺點:

  • 當產品族中需要增加一個新的產品時,所有的工廠類都需要進行修改。增加了系統的抽象性和理解難度。