02-工厂模式
简洁版
以工厂方法模式为例。

- 抽象产品(Abstract Product):定义了产品的共同接口或抽象类。它可以是具体产品类的接口或抽象类,规定了产品对象的共同方法。
- 具体产品(Concrete Product):实现了抽象产品接口,定义了具体产品的特定行为和属性。
- 抽象工厂(Abstract Factory):声明了创建产品的抽象方法,可以是接口或抽象类。它可以有多个方法用于创建不同类型的产品。
- 具体工厂(Concrete Factory):实现了抽象工厂接口,负责实际创建具体产品的对象。
聊天机器人需要处理不同类型的消息,如文本、语音、图像等。使用工厂方法模式为不同类型的消息创建相应的处理器。
- 消息处理器接口
- 具体的文本消息处理器
- 具体的语音消息处理器
- 处理器工厂接口
- 具体的文本消息处理器工厂
- 具体的语音消息处理器工厂
- 客户端
客户端代码参考:
// 客户端代码
public class Client {
public static void main(String[] args) {
Factory factoryA = new ConcreteFactoryA();
Product productA = factoryA.createProduct();
productA.use();
Factory factoryB = new ConcreteFactoryB();
Product productB = factoryB.createProduct();
productB.use();
}
}
Chat GPT
工厂模式(Factory Pattern)是一种创建型设计模式,它提供了一种创建对象的接口,但由子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
在Java中,工厂模式可以通过以下几种方式实现:
1. 简单工厂模式(Simple Factory)
这是最基本的工厂模式,通常也被称为静态工厂方法。我们使用一个单独的类来创建对象。
// 产品接口
interface Product {
void use();
}
// 具体产品A
class ConcreteProductA implements Product {
@Override
public void use() {
System.out.println("Using Product A");
}
}
// 具体产品B
class ConcreteProductB implements Product {
@Override
public void use() {
System.out.println("Using Product B");
}
}
// 简单工厂类
class SimpleFactory {
public static Product createProduct(String type) {
if (type.equals("A")) {
return new ConcreteProductA();
} else if (type.equals("B")) {
return new ConcreteProductB();
}
throw new IllegalArgumentException("Unknown product type");
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
Product productA = SimpleFactory.createProduct("A");
productA.use();
Product productB = SimpleFactory.createProduct("B");
productB.use();
}
}
2. 工厂方法模式(Factory Method)
这种模式使用抽象类或者接口来声明工厂方法,而具体的工厂由子类实现。
// 产品接口
interface Product {
void use();
}
// 具体产品A
class ConcreteProductA implements Product {
@Override
public void use() {
System.out.println("Using Product A");
}
}
// 具体产品B
class ConcreteProductB implements Product {
@Override
public void use() {
System.out.println("Using Product B");
}
}
// 抽象工厂
interface Factory {
Product createProduct();
}
// 具体工厂A
class ConcreteFactoryA implements Factory {
@Override
public Product createProduct() {
return new ConcreteProductA();
}
}
// 具体工厂B
class ConcreteFactoryB implements Factory {
@Override
public Product createProduct() {
return new ConcreteProductB();
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
Factory factoryA = new ConcreteFactoryA();
Product productA = factoryA.createProduct();
productA.use();
Factory factoryB = new ConcreteFactoryB();
Product productB = factoryB.createProduct();
productB.use();
}
}
3. 抽象工厂模式(Abstract Factory)
这是工厂模式的扩展,提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们的具体类。
// 产品接口
interface ProductA {
void use();
}
interface ProductB {
void eat();
}
// 具体产品A1
class ConcreteProductA1 implements ProductA {
@Override
public void use() {
System.out.println("Using Product A1");
}
}
// 具体产品A2
class ConcreteProductA2 implements ProductA {
@Override
public void use() {
System.out.println("Using Product A2");
}
}
// 具体产品B1
class ConcreteProductB1 implements ProductB {
@Override
public void eat() {
System.out.println("Eating Product B1");
}
}
// 具体产品B2
class ConcreteProductB2 implements ProductB {
@Override
public void eat() {
System.out.println("Eating Product B2");
}
}
// 抽象工厂
interface AbstractFactory {
ProductA createProductA();
ProductB createProductB();
}
// 具体工厂1
class ConcreteFactory1 implements AbstractFactory {
@Override
public ProductA createProductA() {
return new ConcreteProductA1();
}
@Override
public ProductB createProductB() {
return new ConcreteProductB1();
}
}
// 具体工厂2
class ConcreteFactory2 implements AbstractFactory {
@Override
public ProductA createProductA() {
return new ConcreteProductA2();
}
@Override
public ProductB createProductB() {
return new ConcreteProductB2();
}
}
// 客户端代码
public class Client {
public static void main(String[] args) {
AbstractFactory factory1 = new ConcreteFactory1();
ProductA productA1 = factory1.createProductA();
ProductB productB1 = factory1.createProductB();
productA1.use();
productB1.eat();
AbstractFactory factory2 = new ConcreteFactory2();
ProductA productA2 = factory2.createProductA();
ProductB productB2 = factory2.createProductB();
productA2.use();
productB2.eat();
}
}
项目应用
在一个智能聊天机器人系统中,工厂方法模式可以应用于多个场景,以提高系统的灵活性和可扩展性。以下是一些可能使用工厂方法模式的地方:
1. 消息处理器(Message Processor)
聊天机器人需要处理不同类型的消息,如文本、语音、图像等。我们可以使用工厂方法模式为不同类型的消息创建相应的处理器。
// 消息处理器接口
interface MessageProcessor {
void processMessage(String message);
}
// 具体的文本消息处理器
class TextMessageProcessor implements MessageProcessor {
@Override
public void processMessage(String message) {
System.out.println("Processing text message: " + message);
}
}
// 具体的语音消息处理器
class VoiceMessageProcessor implements MessageProcessor {
@Override
public void processMessage(String message) {
System.out.println("Processing voice message: " + message);
}
}
// 处理器工厂接口
interface MessageProcessorFactory {
MessageProcessor createProcessor();
}
// 具体的文本消息处理器工厂
class TextMessageProcessorFactory implements MessageProcessorFactory {
@Override
public MessageProcessor createProcessor() {
return new TextMessageProcessor();
}
}
// 具体的语音消息处理器工厂
class VoiceMessageProcessorFactory implements MessageProcessorFactory {
@Override
public MessageProcessor createProcessor() {
return new VoiceMessageProcessor();
}
}
客户端
public class MessageProcessorClient {
public static void main(String[] args) {
// 假设我们有一些消息
String textMessage = "Hello, this is a text message!";
String voiceMessage = "Voice message content";
// 处理文本消息
processMessage(textMessage, "text");
// 处理语音消息
processMessage(voiceMessage, "voice");
}
public static void processMessage(String message, String messageType) {
// 根据消息类型选择合适的工厂
MessageProcessorFactory factory;
if (messageType.equals("text")) {
factory = new TextMessageProcessorFactory();
} else if (messageType.equals("voice")) {
factory = new VoiceMessageProcessorFactory();
} else {
throw new IllegalArgumentException("Unsupported message type: " + messageType);
}
// 使用工厂创建处理器并处理消息
MessageProcessor processor = factory.createProcessor();
processor.processMessage(message);
}
}
2. 个性化服务提供器(Personalized Service Provider)
智能聊天机器人需要根据用户的偏好和历史数据提供个性化服务,如推荐系统、个性化问候等。我们可以使用工厂方法模式为不同用户类型创建相应的服务提供器。
// 个性化服务接口
interface PersonalizedService {
void provideService(String user);
}
// 具体的推荐服务
class RecommendationService implements PersonalizedService {
@Override
public void provideService(String user) {
System.out.println("Providing recommendations for user: " + user);
}
}
// 具体的问候服务
class GreetingService implements PersonalizedService {
@Override
public void provideService(String user) {
System.out.println("Greeting user: " + user);
}
}
// 服务提供器工厂接口
interface ServiceProviderFactory {
PersonalizedService createService();
}
// 具体的推荐服务提供器工厂
class RecommendationServiceProviderFactory implements ServiceProviderFactory {
@Override
public PersonalizedService createService() {
return new RecommendationService();
}
}
// 具体的问候服务提供器工厂
class GreetingServiceProviderFactory implements ServiceProviderFactory {
@Override
public PersonalizedService createService() {
return new GreetingService();
}
}
客户端
public class PersonalizedServiceClient {
public static void main(String[] args) {
// 假设我们有一些用户
String user1 = "Alice";
String user2 = "Bob";
// 为用户提供推荐服务
provideService(user1, "recommendation");
// 为用户提供问候服务
provideService(user2, "greeting");
}
public static void provideService(String user, String serviceType) {
// 根据服务类型选择合适的工厂
ServiceProviderFactory factory;
if (serviceType.equals("recommendation")) {
factory = new RecommendationServiceProviderFactory();
} else if (serviceType.equals("greeting")) {
factory = new GreetingServiceProviderFactory();
} else {
throw new IllegalArgumentException("Unsupported service type: " + serviceType);
}
// 使用工厂创建服务并提供服务
PersonalizedService service = factory.createService();
service.provideService(user);
}
}
3. 多功能支持模块(Multi-Function Support Module)
聊天机器人可能支持多种功能,如天气查询、新闻推送、定时提醒等。我们可以使用工厂方法模式为不同功能创建相应的支持模块。
// 功能支持接口
interface FunctionSupport {
void execute(String command);
}
// 具体的天气查询功能支持
class WeatherSupport implements FunctionSupport {
@Override
public void execute(String command) {
System.out.println("Executing weather command: " + command);
}
}
// 具体的新闻推送功能支持
class NewsSupport implements FunctionSupport {
@Override
public void execute(String command) {
System.out.println("Executing news command: " + command);
}
}
// 支持模块工厂接口
interface FunctionSupportFactory {
FunctionSupport createSupport();
}
// 具体的天气查询支持工厂
class WeatherSupportFactory implements FunctionSupportFactory {
@Override
public FunctionSupport createSupport() {
return new WeatherSupport();
}
}
// 具体的新闻推送支持工厂
class NewsSupportFactory implements FunctionSupportFactory {
@Override
public FunctionSupport createSupport() {
return new NewsSupport();
}
}
客户端
public class FunctionSupportClient {
public static void main(String[] args) {
// 假设我们有一些命令
String weatherCommand = "Get weather for New York";
String newsCommand = "Get latest news";
// 执行天气查询命令
executeCommand(weatherCommand, "weather");
// 执行新闻推送命令
executeCommand(newsCommand, "news");
}
public static void executeCommand(String command, String supportType) {
// 根据支持类型选择合适的工厂
FunctionSupportFactory factory;
if (supportType.equals("weather")) {
factory = new WeatherSupportFactory();
} else if (supportType.equals("news")) {
factory = new NewsSupportFactory();
} else {
throw new IllegalArgumentException("Unsupported support type: " + supportType);
}
// 使用工厂创建支持对象并执行命令
FunctionSupport support = factory.createSupport();
support.execute(command);
}
}
4. 用户会话管理(User Session Management)
聊天机器人需要管理不同用户的会话,每个会话可能需要不同的策略(如缓存策略、持久化策略)。我们可以使用工厂方法模式为不同的会话策略创建相应的管理器。
会话管理器接口和具体实现:
// 会话管理器接口
interface SessionManager {
void manageSession(String user);
}
// 具体的缓存策略会话管理器
class CacheSessionManager implements SessionManager {
@Override
public void manageSession(String user) {
System.out.println("Managing session for user with cache strategy: " + user);
}
}
// 具体的持久化策略会话管理器
class PersistentSessionManager implements SessionManager {
@Override
public void manageSession(String user) {
System.out.println("Managing session for user with persistent strategy: " + user);
}
}
会话管理器工厂接口和具体实现:
// 会话管理器工厂接口
interface SessionManagerFactory {
SessionManager createSessionManager();
}
// 具体的缓存策略会话管理器工厂
class CacheSessionManagerFactory implements SessionManagerFactory {
@Override
public SessionManager createSessionManager() {
return new CacheSessionManager();
}
}
// 具体的持久化策略会话管理器工厂
class PersistentSessionManagerFactory implements SessionManagerFactory {
@Override
public SessionManager createSessionManager() {
return new PersistentSessionManager();
}
}
客户端:
方式一
public class SessionManagerClient {
public static void main(String[] args) {
// 假设我们有一些用户
String user1 = "Alice";
String user2 = "Bob";
// 为用户1使用缓存策略管理会话
manageUserSession(user1, "cache");
// 为用户2使用持久化策略管理会话
manageUserSession(user2, "persistent");
}
public static void manageUserSession(String user, String strategyType) {
// 根据策略类型选择合适的工厂
SessionManagerFactory factory;
if (strategyType.equals("cache")) {
factory = new CacheSessionManagerFactory();
} else if (strategyType.equals("persistent")) {
factory = new PersistentSessionManagerFactory();
} else {
throw new IllegalArgumentException("Unsupported strategy type: " + strategyType);
}
// 使用工厂创建会话管理器并管理会话
SessionManager sessionManager = factory.createSessionManager();
sessionManager.manageSession(user);
}
}
方式二
// 客户端代码
public class Client {
public static void main(String[] args) {
// 为用户1使用缓存策略管理会话
SessionManagerFactory cacheFactory = new CacheSessionManagerFactory();
SessionManager cacheSessionManager = cacheFactory.createSessionManager();
cacheSessionManager.manageSession("Alice");
// 为用户2使用持久化策略管理会话
SessionManagerFactory persistentFactory = new PersistentSessionManagerFactory();
SessionManager persistentSessionManager = persistentFactory.createSessionManager();
persistentSessionManager.manageSession("Bob");
}
}
两种客户端代码区别:
方法调用方式:
- 方式一:通过一个公共的
manageUserSession
方法来处理不同的策略。这个方法内部根据策略类型选择合适的工厂并创建会话管理器。 - 方式二:直接在
main
方法中创建不同的工厂和会话管理器,并调用相应的方法。这种方式更加直接和显式。
- 方式一:通过一个公共的
灵活性和扩展性:
- 方式一:通过传递策略类型字符串来选择工厂。这种方式在添加新策略时需要修改
manageUserSession
方法,增加新的策略判断逻辑。 - 方式二:每种策略都有自己的工厂类,客户端代码直接使用这些工厂类。这种方式在添加新策略时,只需在客户端代码中添加新的工厂实例化和调用,不需要修改现有的方法。
- 方式一:通过传递策略类型字符串来选择工厂。这种方式在添加新策略时需要修改
代码简洁性:
- 方式一:通过一个方法处理所有策略,代码集中在一个地方,显得简洁,但增加了方法的复杂性。
- 方式二:每个策略的处理逻辑分散在不同的代码块中,代码更加直观和易读,但可能显得冗长。
错误处理:
- 方式一:在
manageUserSession
方法中处理不支持的策略类型,抛出异常。 - 方式二:没有集中处理不支持的策略类型,假设客户端代码不会传递不支持的策略类型。
- 方式一:在
选择依据:
方式一适合于策略类型较少且变化不频繁的场景,通过一个方法集中处理所有策略,代码显得简洁。
方式二适合于策略类型较多且变化频繁的场景,通过显式地创建工厂和会话管理器,代码更加直观和易于扩展。