1. 程式人生 > 其它 >設計模式 簡單工廠 工廠 抽象工廠

設計模式 簡單工廠 工廠 抽象工廠

1 簡單工廠模式

1.1 定義

簡單工廠模式又叫靜態工廠模式,但不屬於23種設計模式之一。

簡單來說就是有一個類,提供一個建立方法createProduct,根據接收到的值決定例項化哪個類,但是這個簡單工廠類能例項化的類必須都是同一個抽象類下的子類

1.2 實際應用場景

在JDK的類庫中廣泛使用了這個模式,比如DateFormat,可以看到根據傳入的引數不同,返回不同DateFormat類的子類

1.3 手動實現

為了便於學習,程式碼都寫在一個檔案下

public class SimpleFactory {

    /**
     * 提供一個createProduct方法,根據傳入的引數決定要建立哪個類的物件
     * @param type
     * @return
     */
    public static Product createProduct(String type) {
        if ("A".equals(type)) {
            return new ProductA();
        } else {
            return new ProductB();
        }
    }

    public static void main(String[] args) {
        Product product = SimpleFactory.createProduct("A");
        product.print();
    }

}
    /**
     * 建立一個抽象類 宣告一個抽象方法
     */
    abstract class Product{
        public abstract void print();
    }

    /**
     * 建立抽象類的子類A 實現抽象方法
     */
    class ProductA extends Product{

        @Override
        public void print() {
            System.out.println("產品A建立了");
        }
    }

    /**
     * 建立抽象類的子類B 實現抽象方法
     */
    class ProductB extends Product{

        @Override
        public void print() {
            System.out.println("產品B建立了");
        }
    }


1.4 優缺點

  • 拓展:開閉原則

    程式對於拓展是開放的,對於修改是封閉的,核心觀點:拓展優於修改

優點:實現了物件的建立和使用的分離,建立完全交給專門的工廠類負責,客戶端程式設計師無需關心物件如何建立,只需要關心怎麼使用

缺點:簡單工廠模式不夠靈活,每次新增產品類就要修改工廠類的判斷邏輯,如果產品類很多,這個邏輯就會很複雜,同時修改工廠類違反了開閉原則

2 工廠模式

2.1 定義

簡單來說就是隻定義一個工廠類介面,再實現介面得到不同的子工廠類,讓子工廠類分別負責不同的產品類的建立,而這些產品類依然屬於同一個介面下不同的實現類

2.2 對比簡單工廠模式

簡單工廠模式

建立一個工廠類,每當新增一個產品類時就要修改工廠類

工廠模式

定義一個工廠介面,只給出工廠類要實現的方法,而不再負責建立物件,轉而由工廠介面的各個實現類去建立物件,每當新增一個產品類時,只需要建立一個新的工廠類

2.3 實際應用場景

最常見的集合類Collection只是一個介面,對應著就是一個工廠介面,而具體的子類比如Arraylist,實現collection介面,就是一個實現了工廠介面的工廠類。

ArrayList能建立itr的例項,而itr是Iterator的實現類,因此整個過程就是一個工廠模式的運用。

類圖如下

collection就是抽象工廠,具體工廠就是LinkedList,ArrayList,Iteratior就是抽象產品,具體產品就是ListItr和Itr,他們分別由LinkedList和ArrayList建立

2.4 手動實現

為了便於學習,將程式碼都放在一個檔案下

public class FactoryPattern {
    public static void main(String[] args) {
        Factory factory = new ProductAFactory();
        Product product = factory.create();
        product.print();
    }
}

/**
 * 建立產品類介面
 */
interface Product{
    void print();
}

/**
 * 建立產品子類A並實現介面
 */
class ProductA implements Product{

    @Override
    public void print() {
        System.out.println("產品A被建立了");
    }
}

/**
 * 建立產品子類B並實現介面
 */
class ProductB implements Product{

    @Override
    public void print() {
        System.out.println("產品B被建立了");
    }
}

/**
 * 建立工廠介面
 */
interface Factory{
    Product create();
}

/**
 * 建立工廠子類A並生產產品子類A
 */
class ProductAFactory implements Factory{

    @Override
    public Product create() {
        return new ProductA();
    }
}

/**
 * 建立工廠子類B並生產產品子類B
 */
class ProductBFactory implements Factory{

    @Override
    public Product create() {
        return new ProductB();
    }
}

2.5 優缺點

優點:解決了簡單工廠模式違反開閉原則的問題

缺點:工廠模式的每一個子工廠類只能建立固定的某個產品類,每當新增產品類時,就得新增一個子工廠類

3 抽象工廠模式

3.1 定義

簡單來說就是令工廠類和產品類原本一對一的關係變成了一對多,但是如果要擴充套件產品類,那麼還是要修改工廠介面和各個子工廠類的程式碼,違反開閉原則

3.2 對比工廠模式

  1. 抽象工廠模式解決了工廠模式的工廠類和產品類一一對應的缺點,每個工廠類可以建立其他產品類,但是抽象工廠模式的擴充套件性和簡單工廠模式一樣差,會違反開閉原則。

  2. 工廠方法模式對具體產品可擴充套件,抽象工廠模式對具體產品族可擴充套件

  3. 抽象工廠模式只是工廠模式的一個擴充套件,如果只有一個產品類,那麼抽象工廠模式就會退化成工廠模式

3.3 手動實現

為了便於學習,將程式碼都放在一個檔案下

/**
 * 抽象工廠
 */
interface AbstractFactory{
    Phone createPhone(String param);
    Mask createMask(String param);
}

/**
 * 具體工廠 可以建立產品A和B 即工廠類和產品類實現了一對多
 */
class SuperFactory implements AbstractFactory{

    @Override
    public Phone createPhone(String param) {
        if ("A".equals(param)) {
            return new iphone();
        }else{
            return new huawei();
        }
    }

    @Override
    public Mask createMask(String param) {
        if ("C".equals(param)){
            return new N95();
        }else {
            return new normal();
        }
    }
}

/**
 * 抽象產品A
 */
interface Phone{}

/**
 * 具體產品A和B
 */
class iphone implements Phone{}
class huawei implements Phone{}

/**
 * 抽象產品B
 */
interface Mask{}
/**
 * 具體產品C和D
 */
class N95 implements Mask{}
class normal implements Mask{}