java设计模式:02-04-抽象工厂模式

抽象工厂模式(Abstract Factory Pattern)

抽象工厂模式(Abstract Factory Pattern)提供一个接口,用于创建一系列相关或相互依赖的对象,而无需指定它们的具体类。它属于创建型设计模式。

抽象工厂模式的应用场景

  • 当一个系统要独立于它的产品创建、组合和表示时:系统不应依赖于产品类如何被创建、组合和表示。
  • 当一个系统要由多个产品系列中的一个来配置时:例如,图形界面库中不同的主题(Windows风格、Mac风格)需要不同的控件样式。
  • 当需要提供一个产品类库,而只需显示其接口而不需要实现时:例如,数据库驱动程序的实现。

抽象工厂模式的实现方式

1. 传统实现方式

思想:通过定义抽象工厂接口以及具体工厂类,每个具体工厂负责创建一系列相关的产品。

实现方式

java 复制代码
// 产品接口
interface Button {
    void paint();
}

interface Checkbox {
    void paint();
}

// 具体产品类
class WindowsButton implements Button {
    public void paint() {
        System.out.println("Rendering a button in Windows style.");
    }
}

class MacOSButton implements Button {
    public void paint() {
        System.out.println("Rendering a button in MacOS style.");
    }
}

class WindowsCheckbox implements Checkbox {
    public void paint() {
        System.out.println("Rendering a checkbox in Windows style.");
    }
}

class MacOSCheckbox implements Checkbox {
    public void paint() {
        System.out.println("Rendering a checkbox in MacOS style.");
    }
}

// 抽象工厂接口
interface GUIFactory {
    Button createButton();
    Checkbox createCheckbox();
}

// 具体工厂类
class WindowsFactory implements GUIFactory {
    public Button createButton() {
        return new WindowsButton();
    }

    public Checkbox createCheckbox() {
        return new WindowsCheckbox();
    }
}

class MacOSFactory implements GUIFactory {
    public Button createButton() {
        return new MacOSButton();
    }

    public Checkbox createCheckbox() {
        return new MacOSCheckbox();
    }
}

// 客户端代码
public class AbstractFactoryPattern {
    private static Application configureApplication() {
        Application app;
        GUIFactory factory;
        String osName = System.getProperty("os.name").toLowerCase();
        if (osName.contains("mac")) {
            factory = new MacOSFactory();
            app = new Application(factory);
        } else {
            factory = new WindowsFactory();
            app = new Application(factory);
        }
        return app;
    }

    public static void main(String[] args) {
        Application app = configureApplication();
        app.paint();
    }
}

// 应用类
class Application {
    private Button button;
    private Checkbox checkbox;

    public Application(GUIFactory factory) {
        button = factory.createButton();
        checkbox = factory.createCheckbox();
    }

    public void paint() {
        button.paint();
        checkbox.paint();
    }
}

优点

  • 分离具体类的创建,使得客户端代码与具体实现解耦。
  • 符合开闭原则(对扩展开放,对修改关闭),可以通过增加具体工厂来扩展产品系列。

缺点

  • 增加了系统的复杂度,增加了新的抽象层。
  • 当产品系列需要频繁变化时,会导致类爆炸(类数量急剧增加)。
2. 使用反射实现抽象工厂

思想:通过反射机制,根据配置文件或其他方式动态加载具体工厂类,避免在代码中硬编码具体工厂类。

实现方式

java 复制代码
import java.util.Properties;
import java.io.InputStream;

// 产品接口
interface Button {
    void paint();
}

interface Checkbox {
    void paint();
}

// 具体产品类
class WindowsButton implements Button {
    public void paint() {
        System.out.println("Rendering a button in Windows style.");
    }
}

class MacOSButton implements Button {
    public void paint() {
        System.out.println("Rendering a button in MacOS style.");
    }
}

class WindowsCheckbox implements Checkbox {
    public void paint() {
        System.out.println("Rendering a checkbox in Windows style.");
    }
}

class MacOSCheckbox implements Checkbox {
    public void paint() {
        System.out.println("Rendering a checkbox in MacOS style.");
    }
}

// 抽象工厂接口
interface GUIFactory {
    Button createButton();
    Checkbox createCheckbox();
}

// 具体工厂类
class WindowsFactory implements GUIFactory {
    public Button createButton() {
        return new WindowsButton();
    }

    public Checkbox createCheckbox() {
        return new WindowsCheckbox();
    }
}

class MacOSFactory implements GUIFactory {
    public Button createButton() {
        return new MacOSButton();
    }

    public Checkbox createCheckbox() {
        return new MacOSCheckbox();
    }
}

// 工厂生成器类
class FactoryGenerator {
    public static GUIFactory getFactory() {
        GUIFactory factory = null;
        try {
            Properties prop = new Properties();
            InputStream input = FactoryGenerator.class.getClassLoader().getResourceAsStream("config.properties");
            prop.load(input);
            String factoryClass = prop.getProperty("factory.class");
            factory = (GUIFactory) Class.forName(factoryClass).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return factory;
    }
}

// 客户端代码
public class AbstractFactoryPatternReflection {
    private static Application configureApplication() {
        GUIFactory factory = FactoryGenerator.getFactory();
        return new Application(factory);
    }

    public static void main(String[] args) {
        Application app = configureApplication();
        app.paint();
    }
}

// 应用类
class Application {
    private Button button;
    private Checkbox checkbox;

    public Application(GUIFactory factory) {
        button = factory.createButton();
        checkbox = factory.createCheckbox();
    }

    public void paint() {
        button.paint();
        checkbox.paint();
    }
}

优点

  • 动态加载具体工厂类,提升了灵活性。
  • 减少了硬编码依赖,提升了代码的可维护性。

缺点

  • 依赖配置文件和反射机制,增加了配置和调试的复杂度。
  • 反射机制在一定程度上影响性能。

总结

实现方式 优点 缺点
传统实现方式 分离具体类的创建,符合开闭原则,扩展性好 增加了系统的复杂度,增加了新的抽象层,类数量增加
使用反射实现 动态加载具体工厂类,减少硬编码依赖,提升灵活性 依赖配置文件和反射机制,增加了配置和调试的复杂度,影响性能

选择哪种实现方式应根据具体的需求和系统的复杂度来决定。如果系统对产品系列的扩展性要求较高且变化频繁,传统实现方式更适合。如果系统需要动态加载具体工厂类以提高灵活性,可以考虑使用反射机制实现。

相关推荐
reddingtons3 小时前
【游戏宣发】PS “生成式扩展”流,30秒无损适配全渠道KV
游戏·设计模式·新媒体运营·prompt·aigc·教育电商·游戏美术
李慕婉学姐3 小时前
【开题答辩过程】以《基于JAVA的校园即时配送系统的设计与实现》为例,不知道这个选题怎么做的,不知道这个选题怎么开题答辩的可以进来看看
java·开发语言·数据库
奋进的芋圆5 小时前
Java 延时任务实现方案详解(适用于 Spring Boot 3)
java·spring boot·redis·rabbitmq
sxlishaobin5 小时前
设计模式之桥接模式
java·设计模式·桥接模式
model20055 小时前
alibaba linux3 系统盘网站迁移数据盘
java·服务器·前端
荒诞硬汉5 小时前
JavaBean相关补充
java·开发语言
提笔忘字的帝国6 小时前
【教程】macOS 如何完全卸载 Java 开发环境
java·开发语言·macos
2501_941882486 小时前
从灰度发布到流量切分的互联网工程语法控制与多语言实现实践思路随笔分享
java·开发语言
華勳全栈6 小时前
两天开发完成智能体平台
java·spring·go
alonewolf_996 小时前
Spring MVC重点功能底层源码深度解析
java·spring·mvc