Java設計模式 - 工廠模式

 工廠模式能夠將對象的創建和使用解耦,且當創建一個對象的過程繁雜時,又有大量地方需要重複創建該對象,使用工廠模式則可以降低代碼的重複率。另外,將對象的創建封裝到工廠類,當創建過程發生改變時,可直接修改工廠類,而無需到每個創建對象的地方修改代碼,降低了系統的維護成本

目錄

一、簡單工廠模式

1.定義

2.角色:

3.特點

4.示例

二、工廠方法模式

1.定義

2.角色

3.特點

4.示例

三、抽象工廠類

1.定義

2.角色

3.特點

4.示例


一、簡單工廠模式

1.定義

又稱靜態工廠模式,該模式定義一個專門的類負責實例的創建,被創建的實例通常有相同的父類。

2.角色:

  • Factory:工廠類,根據參數的不同創建不同的實例
  • Product:抽象產品類
  • ConcreteProduct:具體產品類

3.特點

  • 優點:將對象的創建和對象本身業務處理分離,降低系統耦合度。
  • 缺點:因爲對象的創建交由工廠處理,當產品種類過多時,需要修改工廠方法,不符合開閉原則,且將使得工廠方法邏輯複雜,不易於維護和擴展。

4.示例

產品接口:

public interface Product {

    void say();
}

具體產品類:

// ConcreteProductA

public class ConcreteProductA implements Product {


    @Override
    public void say() {
        System.out.println("I'm Product A.");
    }
}


// ConcreteProductB

public class ConcreteProductB implements Product {


    @Override
    public void say() {
        System.out.println("I'm Product B.");
    }
}

工廠類:

public class Factory {

    public static Product createProduct(String arg) {

        if (arg == "A")
            return new ConcreteProductA();
        else if (arg == "B")
            return new ConcreteProductB();
        return null;
    }
}

測試類: 

public class TestSimpleFactory {

    public static void main(String[] args) {

        Product productA = Factory.createProduct("A");
        Product productB = Factory.createProduct("B");

        productA.say();
        productB.say();
    }
}


// 輸出
// I'm Product A.
// I'm Product B.

二、工廠方法模式

1.定義

定義了一個創建對象的接口,但由子類決定要實例化的對象是哪一個,該模式讓類把實例化推遲到子類。

2.角色

  • Product:抽象產品類
  • ConcreteProduct:具體產品類
  • Factory:抽象工廠類
  • ConcreteFactory:具體工廠類

3.特點

  • 優點:實例的創建延遲到子類執行,由子類來確定創建何種實例,當有新產品加入時,只需要添加一個新工廠和新產品而無需修改現有系統。
  • 缺點:因爲產品和工廠是成對增加,一定程度上增加了系統的複雜度。

4.示例

產品接口及具體產品類同上

工廠接口:

public interface Factory {

    Product createProduct();
}

具體工廠接口:

// ConcreteFactoryA

public class ConcreteFactoryA implements Factory {

    @Override
    public Product createProduct() {
        return new ConcreteProductA();
    }
}


// ConcreteFactoryB

public class ConcreteFactoryB implements Factory {

    @Override
    public Product createProduct() {
        return new ConcreteProductB();
    }
}

測試類:

public class TestFactoryMethod {

    public static void main(String[] args) {

        Factory factoryA = new ConcreteFactoryA();
        Factory factoryB = new ConcreteFactoryB();
        Product productA = factoryA.createProduct();
        Product productB = factoryB.createProduct();

        productA.say();
        productB.say();
    }
}

// 輸出
// I'm Product A.
// I'm Product B.

三、抽象工廠類

1.定義

提供一個接口,用於創建相關或依賴對象的家族,而不需要明確指定具體類。

2.角色

  • AbstractProduct:抽象產品類
  • ConcreteProduct:具體產品類
  • AbstractFactory:抽象工廠類
  • ConcreteFactory:具體工廠類

3.特點

  • 優點:可通過具體工廠類創建產品族的多個對象。
  • 缺點:其開閉原則具有傾斜性,即增加或者修改產品族比較方便,可直接增加新的具體工廠和產品族,但增加新的產品等級結構很複雜,需要修改抽象工廠和所有的具體工廠類。

4.示例

產品接口及其具體產品類:

// AbstractProductA

public interface AbstractProductA {

    void use();
}


// AbstractProductB

public interface AbstractProductB {

    void eat();
}


// ProductA1
public class ProductA1 implements AbstractProductA {

    @Override
    public void use() {
        System.out.println("I'm using ProductA1.");
    }
}


// ProductA2
public class ProductA2 implements AbstractProductA {

    @Override
    public void use() {
        System.out.println("I'm using ProductA2.");
    }
}


// ProductB1
public class ProductB1 implements AbstractProductB {

    @Override
    public void eat() {
        System.out.println("I'm eating ProductB1.");
    }
}


// ProductB2
public class ProductB2 implements AbstractProductB {

    @Override
    public void eat() {
        System.out.println("I'm eating ProductB2.");
    }
}

工廠接口及其具體工廠類:

// Factory
public interface Factory {

    AbstractProductA createProductA();
    AbstractProductB createProductB();
}


// ConcreteFactory1
public class ConcreteFactory1 implements Factory {

    @Override
    public AbstractProductA createProductA() {
        return new ProductA1();
    }

    @Override
    public AbstractProductB createProductB() {
        return new ProductB1();
    }
}


// ConcreteFactory2
public class ConcreteFactory2 implements Factory {

    @Override
    public AbstractProductA createProductA() {
        return new ProductA2();
    }

    @Override
    public AbstractProductB createProductB() {
        return new ProductB2();
    }
}

測試類:

public class TestAbstractFactory {

    public static void main(String[] args) {

        Factory factory1 = new ConcreteFactory1();
        AbstractProductA productA1 = factory1.createProductA();
        AbstractProductB productB1 = factory1.createProductB();
        productA1.use();
        productB1.eat();

        Factory factory2 = new ConcreteFactory2();
        AbstractProductA productA2 = factory2.createProductA();
        AbstractProductB productB2 = factory2.createProductB();
        productA2.use();
        productB2.eat();
    }
}


// 輸出
// I'm using ProductA1.
// I'm eating ProductB1.
// I'm using ProductA2.
// I'm eating ProductB2.

 

參考:

1.《Head First 設計模式》

2.圖說設計模式 https://design-patterns.readthedocs.io/zh_CN/latest/index.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章