首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 創建型模式入門:簡單工廠模式實戰與核心原理解析

     編輯:Java 相關知識

創建型模式的核心使命是將物件的建立過程封裝起來,使「建立責任」與「使用責任」分離。簡單工廠模式作為工廠家族的入門形態,雖不屬於 GoF 23 種經典模式,卻是理解工廠方法、抽象工廠的基石。本文通過「小花果園」種植水果的生動案例,系統講解簡單工廠的結構、實現與應用場景。

一、為何需要工廠模式?

Java 使用 new 建立物件:

StringBuffer sb = new StringBuffer(1000);

缺點:

  1. 硬編碼類名:編譯期必須確定具體類
  2. 建立與使用耦合:業務邏輯混雜著建構細節
  3. 違反開閉原則:新增類型需修改客戶端代碼

工廠模式解決方案:由專門的工廠類負責實例化,客戶端僅依賴產品介面。

二、案例演進:從花園到果園

1. 產品介面與實現


public interface FruitIF {
    void plant();      // 種植
    void grow();       // 生長
    void harvest();    // 收穫
    String getColor();
    String getName();
}

// 蘋果:多年生木本,有樹齡屬性
public class Apple implements FruitIF {
    private int treeAge;
    public void plant() { log("Apple has been planted."); }
    public void grow() { log("Apple is growing..."); }
    public void harvest() { log("Apple has been harvested."); }
    // getter/setter ...
}

// 葡萄:有籽/無籽屬性
public class Grape implements FruitIF { ... }

// 草莓:一年生草本
public class Strawberry implements FruitIF { ... }

2. 簡單工廠類:FruitGardener


public class FruitGardener {
    public FruitIF factory(String which) throws BadFruitException {
        if (which.equalsIgnoreCase("apple")) {
            return new Apple();
        } else if (which.equalsIgnoreCase("strawberry")) {
            return new Strawberry();
        } else if (which.equalsIgnoreCase("grape")) {
            return new Grape();
        } else {
            throw new BadFruitException("Bad fruit request: " + which);
        }
    }
}

3. 客戶端使用


try {
    FruitGardener gardener = new FruitGardener();
    FruitIF apple = gardener.factory("apple");
    FruitIF grape = gardener.factory("grape");
    apple.plant(); apple.grow(); apple.harvest();
} catch (BadFruitException e) {
    // 處理非法請求
}

三、簡單工廠模式正式定義

UML 結構

簡單工廠模式類圖

角色定義

角色類名職責
工廠類Creator (FruitGardener)根據參數決定建立哪個具體產品實例
抽象產品Product (FruitIF)定義產品共同介面
具體產品ConcreteProduct (Apple, Grape...)實作產品介面

框架代碼


public class Creator {
    public Product factory() {
        return new ConcreteProduct();
    }
}

public interface Product { }

public class ConcreteProduct implements Product {
    public ConcreteProduct() {}
}

四、簡單工廠 vs 工廠方法:關鍵差異

維度簡單工廠工廠方法
核心類單一具體工廠類抽象工廠介面/類 + 多個具體工廠子類
擴展新產品修改工廠類源碼(違反 OCP)新增具體工廠子類(符合 OCP)
適用場景產品類型固定、數量少產品族擴展頻繁、多維度變化

本質關係:簡單工廠是工廠方法的退化特例——當系統確定只需一個工廠類時,將抽象工廠合併到具體工廠中即得簡單工廠。

五、練習題:繪圖員系統

需求:支援圓形、方形、三角形繪製與擦除,非法形狀拋出異常。

UML 設計

繪圖員系統類圖

核心代碼


public interface Shape {
    void draw();
    void erase();
}

public class Circle implements Shape {
    public void draw() { System.out.println("Circle.draw()"); }
    public void erase() { System.out.println("Circle.erase()"); }
}
// Square, Triangle 類似...

public class BadShapeException extends Exception {
    public BadShapeException(String msg) { super(msg); }
}

public class ArtTracer {
    public Shape factory(String which) throws BadShapeException {
        if (which.equalsIgnoreCase("circle")) return new Circle();
        else if (which.equalsIgnoreCase("square")) return new Square();
        else if (which.equalsIgnoreCase("triangle")) return new Triangle();
        else throw new BadShapeException("Unsupported shape: " + which);
    }
}

使用示例


try {
    ArtTracer art = new ArtTracer();
    art.factory("circle").draw();
    art.factory("diamond"); // 拋出 BadShapeException
} catch (BadShapeException e) { ... }

六、常見問題答疑

  1. Q: 工廠模式不是為了避免 new 嗎?為何實現中仍用 new?
    A: 工廠模式將 new 細節封裝在工廠內部,對整個系統而言,客戶端不再直接依賴具體類的建構細節。
  2. Q: 定義類圖中為何只有一個 ConcreteProduct?
    A: 類圖是框架性定義,實際產品數量視具體系統而定。
  3. Q: factory() 方法能否設為 static?
    A: 可以。本文使用實例方法是為了與後續的工廠方法模式(需多態)形成對比。

七、總結

簡單工廠模式以單一工廠類 + 參數判斷實現物件建立封裝,適合產品類型較固定、變化頻率低的場景。它是理解更高階工廠模式的基石——當系統需要支援多維度產品變化(如水果/蔬菜/花卉並存)時,簡單工廠將退化為「上帝類」,此時需進化為工廠方法模式或抽象工廠模式。掌握簡單工廠的優缺邊界,是架構演進判斷力的關鍵體現。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved