目录

23种设计模式之抽象工厂模式-核心原理与-Java实践

23种设计模式之【抽象工厂模式】-核心原理与 Java实践

抽象工厂模式(Abstract Factory Pattern)

抽象工厂模式是 23 种设计模式中的一种创建型模式,其核心思想是提供一个接口,用于创建一系列相关或相互依赖的对象,而无需指定它们具体的类。这种模式专注于创建 “产品族”(即一组相关产品),通过抽象工厂的不同实现,客户端可以切换不同的产品族,而无需修改使用产品的代码。

核心原理

抽象工厂(Abstract Factory):
声明创建一系列产品的接口(方法),每个方法对应一种产品类型
定义产品族的创建规范,不涉及具体产品的实现
具体工厂(Concrete Factory):
实现抽象工厂接口,负责创建具体的产品对象
每个具体工厂对应一个产品族,生产该族下的所有产品
抽象产品(Abstract Product):
定义某类产品的接口,描述产品的公共方法
每个抽象产品对应产品族中的一种产品类型
具体产品(Concrete Product):
实现抽象产品接口,是具体工厂创建的目标对象
属于特定产品族,由对应的具体工厂生产

抽象工厂模式的核心是 “产品族的创建与切换”,通过抽象工厂隔离产品的创建细节,使客户端可以在不修改代码的情况下切换不同的产品族,符合开闭原则。

Java 实践示例

以 “电子设备工厂” 为例实现抽象工厂模式:
存在两个产品族:苹果设备(iPhone、MacBook)和三星设备(Galaxy 手机、Samsung 笔记本)
每个产品族包含两种产品:手机(Phone)和电脑(Computer)
通过抽象工厂模式实现不同品牌产品族的创建与切换

package com.example.demo;

public class AbstractFactoryPattern {
    public static void main(String[] args) {
        // 创建苹果产品工厂
        ElectronicsFactory appleFactory = new AppleFactory();
        System.out.println("=== 苹果产品族 ===");
        Phone iphone = appleFactory.createPhone();
        Computer macBook = appleFactory.createComputer();
        iphone.makeCall();
        macBook.runProgram();

        // 创建三星产品工厂
        ElectronicsFactory samsungFactory = new SamsungFactory();
        System.out.println("\n=== 三星产品族 ===");
        Phone galaxy = samsungFactory.createPhone();
        Computer samsungLaptop = samsungFactory.createComputer();
        galaxy.makeCall();
        samsungLaptop.runProgram();
    }

    // 抽象产品:手机
    public interface Phone {
        void makeCall(); // 打电话功能
    }

    // 抽象产品:电脑
    public interface Computer {
        void runProgram(); // 运行程序功能
    }

    // 具体产品:iPhone(苹果手机)
    public static class IPhone implements Phone {
        @Override
        public void makeCall() {
            System.out.println("使用iPhone打电话");
        }
    }

    // 具体产品:MacBook(苹果电脑)
    public static class MacBook implements Computer {
        @Override
        public void runProgram() {
            System.out.println("使用MacBook运行程序");
        }
    }

    // 具体产品:Galaxy手机(三星手机)
    public static class GalaxyPhone implements Phone {
        @Override
        public void makeCall() {
            System.out.println("使用Galaxy手机打电话");
        }
    }

    // 具体产品:Samsung笔记本(三星电脑)
    public static class SamsungLaptop implements Computer {
        @Override
        public void runProgram() {
            System.out.println("使用Samsung笔记本运行程序");
        }
    }

    // 抽象工厂:电子设备工厂
    public interface ElectronicsFactory {
        // 创建手机
        Phone createPhone();

        // 创建电脑
        Computer createComputer();
    }

    // 具体工厂:苹果工厂(生产苹果产品族)
    public static class AppleFactory implements ElectronicsFactory {
        @Override
        public Phone createPhone() {
            return new IPhone(); // 生产iPhone
        }

        @Override
        public Computer createComputer() {
            return new MacBook(); // 生产MacBook
        }
    }

    // 具体工厂:三星工厂(生产三星产品族)
    public static class SamsungFactory implements ElectronicsFactory {
        @Override
        public Phone createPhone() {
            return new GalaxyPhone(); // 生产Galaxy手机
        }

        @Override
        public Computer createComputer() {
            return new SamsungLaptop(); // 生产Samsung笔记本
        }
    }
}

运行结果

=== 苹果产品族 ===
使用iPhone打电话
使用MacBook运行程序

=== 三星产品族 ===
使用Galaxy手机打电话
使用Samsung笔记本运行程序

抽象工厂模式的特点

优点:
隔离具体类的生成:客户端无需知道具体产品的类名,只需关心产品接口
便于交换产品族:更换具体工厂即可切换整个产品族,符合开闭原则
保证产品一致性:同一工厂生产的产品属于同一产品族,确保兼容性
符合依赖倒置原则:依赖抽象(抽象工厂、抽象产品),不依赖具体实现
缺点:
扩展新产品困难:新增产品类型需要修改抽象工厂接口及所有具体工厂
增加系统复杂度:引入多个抽象和具体类,理解和维护成本提高
与工厂方法模式的区别:
工厂方法:专注于创建单一产品,通过继承扩展
抽象工厂:专注于创建产品族(多个相关产品),通过组合扩展

抽象工厂模式的应用场景

产品族相关的创建:
当系统需要处理多个产品族,且产品族内的产品相互关联或依赖
例如:不同品牌的家电(冰箱、洗衣机、空调)组成的产品族
跨平台应用:
为不同平台提供适配的组件族,保证跨平台兼容性
例如:GUI 工具包(Windows、Mac、Linux 的按钮、文本框等组件族)
数据库访问层:
为不同数据库提供统一的访问接口,切换数据库时无需修改业务代码
例如:MySQL 和 Oracle 的 Connection、Statement 等对象组成的产品族
框架设计:
框架需要提供默认实现,同时允许用户扩展自定义实现
例如:Spring 中的BeanFactory及其实现类,创建不同类型的 Bean 对象
主题系统:
应用程序的主题(字体、颜色、布局)作为产品族,支持动态切换
例如:浅色主题和深色主题的 UI 组件族

抽象工厂模式是处理产品族创建的最佳方案,尤其适合需要在不同产品族之间动态切换的场景。它通过将产品族的创建逻辑抽象化,使系统更具灵活性和可扩展性,但在使用时需权衡扩展新产品的复杂度,避免过度设计。