1. 程式人生 > 其它 >23種設計模式(二)工廠模式

23種設計模式(二)工廠模式

簡要概述23種設計模式之工廠模式

二、工廠模式

概念

  • 工廠模式(Factory Pattern)是 Java 中最常用的設計模式之一。這種型別的設計模式屬於建立型模式,它提供了一種建立物件的最佳方式。

  • 在工廠模式中,我們在建立物件時不會對客戶端暴露建立邏輯,並且是通過使用一個共同的介面來指向新建立的物件。

優點

  • 1、一個呼叫者想建立一個物件,只要知道其名稱就可以了。
  • 2、擴充套件性高,如果想增加一個產品,只要擴充套件一個工廠類就可以。
  • 3、遮蔽產品的具體實現,呼叫者只關心產品的介面。

缺點

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

核心本質在於例項化物件不使用new,而用工廠方法來取代,實現瞭解耦。


2.1 簡單工廠模式

簡單工廠模式又被稱為靜態工廠模式,原因在於工廠類定義了一個靜態方法。

下面是一個例項,我們將用程式碼來模擬造車工廠。我們分別用特斯拉(tesla)、賓士(benz)以及大眾(volkswagen)來實現一個總的車子介面。

/**
 * 所有車的統一標準規範類
 *
 * @author kimariyb
 */
public interface Car {
    /**
     * 輸出車子的名字
     */
    void getName();
}

/**
 * 製造特斯拉
 *
 * @author kimariyb
 */
public class Tesla implements Car {
    @Override
    public void getName() {
        System.out.println("這是特斯拉!");
    }
}

/**
 * 製造大眾車
 *
 * @author kimariyb
 */
public class Volkswagen implements Car {
    @Override
    public void getName() {
        System.out.println("這是大眾!");
    }
}

/**
 * 製造賓士車
 *
 * @author kimariyb
 */
public class Benz implements Car {
    @Override
    public void getName() {
        System.out.println("這是賓士!");
    }
}

​ 在這之後,最重要的就在於工廠類的編寫。注意出現的魔法值和一些異常的處理。完成這一切後我們進行測試。在這裡我們直接在類中編寫了(不推薦)。

/**
 * 造車工廠
 *
 * @author kimariyb
 */
public class CarFactory {
    /**
     * 定義靜態常量
     * 防止出現魔法值
     */
    public static final String VOLKSWAGEN = "大眾";
    public static final String BENZ = "賓士";
    public static final String TESLA = "特斯拉";

    public static Car getCar(String car) {
        if (VOLKSWAGEN.equalsIgnoreCase(car)) {
            return new Volkswagen();
        } else if (BENZ.equalsIgnoreCase(car)) {
            return new Benz();
        } else if (TESLA.equalsIgnoreCase(car)) {
            return new Tesla();
        }
        return null;
    }
}

/**
 * 測試類
 *
 * @author kimariyb
 */
public class Test {
    public static void main(String[] args) {
        Car car1 = CarFactory.getCar(CarFactory.BENZ);
        Car car2 = CarFactory.getCar(CarFactory.TESLA);
        Car car3 = CarFactory.getCar(CarFactory.VOLKSWAGEN);
        
        car1.getName();
        car2.getName();
        car3.getName();
    }
}

上面是輸出的結果,可以看見它實現了物件的建立。但是它也有缺點,對於新增的產品,我們只能選擇修改原有程式碼。這並不滿足面向物件的開閉原則


2.2 工廠方法模式

​ 和簡單工廠模式工廠直接負責所有產品的生產相比,工廠方法模式將生產具體產品的任務發給的具體的產品工廠。

​ 還是上面的例項,由於簡單工廠方法並不能滿足開閉原則,我們可以將CarFactory修改為一個介面,並且使用具體車子工廠類來實現這一介面。

/**
 * 車子工廠
 * @author kimariyb
 */
public interface CarFactory {
    /**
     * 得到車子
     * @return 車子
     */
    Car getCar();
}

/**
 * 特斯拉工廠
 *
 * @author kimariyb
 */
public class TeslaFactory implements CarFactory {

    @Override
    public Car getCar() {
        return new Tesla();
    }
}

/**
 * 大眾工廠
 * @author kimariyb
 */
public class VolkswagenFactory implements CarFactory{
    @Override
    public Car getCar() {
        return new Volkswagen();
    }
}

/**
 * 賓士製造工廠
 *
 * @author kimariyb
 */
public class BenzFactory implements CarFactory{
    @Override
    public Car getCar() {
        return new Benz();
    }
}

​ 很顯然這樣可以在不修改原有程式碼的情況下,來實現新增或者減少產品。很好的滿足了開閉原則,下面是測試類和輸出結果。

public class Test {
    public static void main(String[] args) {
        Car car1 = new TeslaFactory().getCar();
        Car car2 = new BenzFactory().getCar();
        Car car3 = new VolkswagenFactory().getCar();

        car1.getName();
        car2.getName();
        car3.getName();
    }
}

簡單工廠和工廠方法模式的不同在於前者生成產生產品的行為封裝在一個方法中,根據引數的型別進行例項化,同時不存在抽象介面。

而後者則通過實現不同的工廠方法來建立不同的產品,一個方法通常對應一個產品,這種方式相較於前者擴充套件性更高,在需求增加時完全符合開閉原則和依賴倒置原則