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

Java 單例模式結合抽象工廠模式的實戰應用解析

     編輯:Java 相關知識

背景

抽象工廠常需全域唯一實例(如配置驅動的工廠),單例模式可確保工廠實例唯一,避免重複初始化資源。

抽象工廠模式速覽

  • 目的:創建一組相關/依賴物件,無需指定具體類。
  • 產品族 vs 產品等級:
    • 等級:同類產品結構(如「轎車」「SUV」)。
    • 族:跨等級的相關產品(如「2.0L 動力總成」含 2.0L 轎車引擎 + 2.0L SUV 引擎)。
  • 工廠方法針對單一等級;抽象工廠針對多等級構成的族。

代碼結構

1. 抽象產品與具體產品

abstract class AbstractProductA { abstract void doSomething(); }
abstract class AbstractProductB { abstract void doSomething(); }

class ProductA1 extends AbstractProductA { void doSomething() { System.out.println("A1"); } }
class ProductA2 extends AbstractProductA { void doSomething() { System.out.println("A2"); } }
class ProductB1 extends AbstractProductB { void doSomething() { System.out.println("B1"); } }
class ProductB2 extends AbstractProductB { void doSomething() { System.out.println("B2"); } }

2. 抽象工廠介面

abstract class AbstractFactory {
    abstract AbstractProductA createProductA();
    abstract AbstractProductB createProductB();
}

3. 具體工廠(各自構成一個產品族)

class Factory1 extends AbstractFactory {
    AbstractProductA createProductA() { return new ProductA1(); }
    AbstractProductB createProductB() { return new ProductB1(); }
}
class Factory2 extends AbstractFactory {
    AbstractProductA createProductA() { return new ProductA2(); }
    AbstractProductB createProductB() { return new ProductB2(); }
}

4. 單例包裝工廠選擇器

public final class FactoryProvider {
    private static final FactoryProvider INSTANCE = new FactoryProvider();
    private AbstractFactory currentFactory;
    
    private FactoryProvider() {} // 私有建構子
    
    public static FactoryProvider getInstance() { return INSTANCE; }
    
    // 依配置切換工廠(運行期僅一個實例)
    public synchronized void setFactory(String type) {
        switch (type) {
            case "type1": currentFactory = new Factory1(); break;
            case "type2": currentFactory = new Factory2(); break;
            default: throw new IllegalArgumentException("Unknown: " + type);
        }
    }
    
    public AbstractFactory getFactory() {
        if (currentFactory == null) throw new IllegalStateException("Factory not initialized");
        return currentFactory;
    }
}

5. 客戶端使用

public class Client {
    public static void main(String[] args) {
        // 系統啟動時依配置初始化一次
        FactoryProvider.getInstance().setFactory("type1");
        
        // 業務代碼僅依賴抽象
        AbstractFactory factory = FactoryProvider.getInstance().getFactory();
        AbstractProductA a = factory.createProductA();
        AbstractProductB b = factory.createProductB();
        a.doSomething(); // 輸出:A1
        b.doSomething(); // 輸出:B1
    }
}

優勢分析

  1. 全域唯一入口:FactoryProvider 單例確保配置一致性,避免多處 new Factory 導致不一致。
  2. 運行期切換族:setFactory() 允許熱切換產品族(如多租戶、多環境)。
  3. 依賴倒置:客戶端僅依賴 AbstractFactory,符合 DIP。
  4. 擴展性:新增產品族只需新增 FactoryN + ProductXN,無需修改現有代碼(OCP)。

注意事項

  • 單例雙重檢查鎖定(DCL)或枚舉實現 FactoryProvider 確保線程安全。
  • setFactory() 加 synchronized 保證切換原子性。
  • 若產品族無動態切換需求,直接用枚舉單例持有工廠實例更簡潔。

總結

單例模式為抽象工廠提供「全域唯一配置入口」,兩者結合實現「產品族集中管理、運行期可切換、客戶端零依賴具體類」的靈活架構,常見於多租戶、多資料源、跨平台適配等場景。

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