你了解工厂模式吗?什么时候使用工厂模式?

72 阅读3分钟

最近几天的项目用到了工厂模式,今天就详细的学习一下工厂模式

什么是工厂模式?

工厂模式是一种创建型的设计模式,用来封装对象的创建逻辑,将实例化的过程从调

用者中抽离出来,交给专门的工厂进行处理。

工厂模式的分类

工厂模式分为三种

  • 简单工厂模式:一个工厂类根据入参创建不同对象(虽然不算严格的设计模式,但 常用)

  • 工厂方法模式:每一个产品对应一个工厂类

  • 抽象工厂模式:用来创建一系列相关的对象如不同品牌的不同的大模型

工厂模式具体的使用

简单工厂

简单工厂是硬编码,一个工厂根据简单的入参来创建不同简单的对象

简单的例子

//接口
public interface Shape {
    void draw();
}
public class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("画一个圆形");
    }
}
//实现类1
public class Rectangle implements Shape {
    @Override
    public void draw() {
        System.out.println("画一个矩形");
    }
}
//实现类2
public class Triangle implements Shape {
    @Override
    public void draw() {
        System.out.println("画一个三角形");
    }
}
//创建工厂
public class ShapeFactory {
    public static Shape createShape(String type) {
        if (type.equalsIgnoreCase("circle")) {
            return new Circle();
        } else if (type.equalsIgnoreCase("rectangle")) {
            return new Rectangle();
        } else if (type.equalsIgnoreCase("triangle")) {
            return new Triangle();
        } else {
            throw new IllegalArgumentException("未知图形类型:" + type);
        }
    }
}
//客户端直接调用
public class Main {
    public static void main(String[] args) {
        Shape shape1 = ShapeFactory.createShape("circle");
        shape1.draw(); // 输出:画一个圆形

        Shape shape2 = ShapeFactory.createShape("rectangle");
        shape2.draw(); // 输出:画一个矩形
    }
}

工厂方法的实现

spring中的例子

//ApplicationContext
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");

详细举例

//产品的接口
public interface Logger {
    void log(String message);
}
//产品1
public class ConsoleLogger implements Logger {
    @Override
    public void log(String message) {
        System.out.println("控制台日志: " + message);
    }
}
//产品2
public class FileLogger implements Logger {
    @Override
    public void log(String message) {
        System.out.println("文件日志: " + message);
    }
}
//定义工厂接口
public interface LoggerFactory {
    Logger createLogger();  // 工厂方法
}
//工厂类1
public class ConsoleLoggerFactory implements LoggerFactory {
    @Override
    public Logger createLogger() {
        return new ConsoleLogger();
    }
}
//工厂类2
public class FileLoggerFactory implements LoggerFactory {
    @Override
    public Logger createLogger() {
        return new FileLogger();
    }
}
//客户端调用
public class Main {
    public static void main(String[] args) {
        LoggerFactory factory = new ConsoleLoggerFactory(); // 想要什么日志,就用哪个工厂
        Logger logger = factory.createLogger();
        logger.log("程序启动成功");

        factory = new FileLoggerFactory();
        Logger fileLogger = factory.createLogger();
        fileLogger.log("写入到日志文件");
    }
}

抽象工厂模式

spring中的例子

BeanFactory factory = new DefaultListableBeanFactory();
((DefaultListableBeanFactory) factory).registerSingleton("myService", new MyServiceImpl());

MyService myService = (MyService) factory.getBean("myService");

详细举例

// 模型的调用模式接口(产品接口)
public interface InvokeMode {
    void invoke(String modelName, String input);
}
// 同步
public class SyncInvoke implements InvokeMode {
    public void invoke(String modelName, String input) {
        System.out.println("[同步] 调用模型 " + modelName + ",输入:" + input);
    }
}
//异步
public class AsyncInvoke implements InvokeMode {
    public void invoke(String modelName, String input) {
        System.out.println("[异步] 调用模型 " + modelName + ",输入:" + input);
    }
}
//流式
public class StreamInvoke implements InvokeMode {
    public void invoke(String modelName, String input) {
        System.out.println("[流式] 调用模型 " + modelName + ",输入:" + input);
    }
}
//定义模型接口工厂
public interface ModelInvokeFactory {
    InvokeMode getSyncInvoker();
    InvokeMode getAsyncInvoker();
    InvokeMode getStreamInvoker();
}
//OpenAIFactory 
public class OpenAIFactory implements ModelInvokeFactory {
    public InvokeMode getSyncInvoker() {
        return new SyncInvoke(); // 也可以是 new OpenAISyncInvoke(),更细分
    }

    public InvokeMode getAsyncInvoker() {
        return new AsyncInvoke();
    }

    public InvokeMode getStreamInvoker() {
        return new StreamInvoke();
    }
}
//BaiduFactory 
public class BaiduFactory implements ModelInvokeFactory {
    public InvokeMode getSyncInvoker() {
        return new SyncInvoke(); // 实际可以有百度的自定义实现
    }

    public InvokeMode getAsyncInvoker() {
        return new AsyncInvoke();
    }

    public InvokeMode getStreamInvoker() {
        return new StreamInvoke();
    }
}
//调用
public class Main {
    public static void main(String[] args) {
        ModelInvokeFactory factory = new OpenAIFactory(); // 可换成 BaiduFactory

        InvokeMode sync = factory.getSyncInvoker();
        InvokeMode async = factory.getAsyncInvoker();
        InvokeMode stream = factory.getStreamInvoker();

        sync.invoke("gpt-4", "你好,写首诗");
        async.invoke("gpt-4", "你好,写首小说");
        stream.invoke("gpt-4", "你好,讲个故事");
    }
}

抽象工厂模式和工厂方法的区别和联系

分析可以看到,其实抽象工厂相比于工厂方法模式,就多在了方法上面 在这里插入图片描述

所以说 工厂方法是创建单一产品 抽象工厂是创建产品族