一、前言
在实际开发中,我们经常面临以下场景:
系统支持多种登录方式(用户名密码、管理员登录、OAuth 登录、短信登录等)
每种登录方式的认证逻辑不同
我们希望对外提供一个统一的接口调用,而不暴露具体实现
这个时候,工厂设计模式(Factory Pattern)就是解决这种需求的最佳利器。
在本文中,我们通过一个模拟登录系统的实际案例,带你深入理解工厂模式的结构、优点和应用场景。
二、什么是工厂模式?
工厂模式是一种创建型设计模式,它通过定义一个用于创建对象的接口,让子类决定实例化哪一个类。这样,我们可以将对象的创建与使用解耦,实现更强的扩展性和可维护性。
通俗地说,工厂模式就像点外卖平台——你只管下单(告诉工厂你想吃什么),工厂帮你创建对应的“菜品实例”,你不需要关心这些菜是怎么做的。
三、代码结构总览
我们使用一个模拟登录系统的例子,分别支持:
普通用户登录(用户名 + 密码)
管理员登录
第三方 OAuth 登录
结构如下:
com.Factory_Pattern
├── LoginService.java // 抽象接口
├── UserLoginService.java // 普通用户登录实现
├── AdminLoginService.java // 管理员登录实现
├── OAuthLoginService.java // OAuth 登录实现
├── LoginFactory.java // 工厂类
└── Test.java // 测试入口
四、核心代码详解
1. 定义统一接口:LoginService
public interface LoginService {
boolean login(String username, String credential);
}
所有登录服务都必须实现这个接口,保证调用方使用统一的方式调用。
2. 三种登录实现类
public class UserLoginService implements LoginService {
@Override
public boolean login(String username, String password) {
System.out.println("普通用户登录验证中...");
return "user".equals(username) && "123".equals(password);
}
}
public class AdminLoginService implements LoginService {
@Override
public boolean login(String username, String password) {
System.out.println("管理员登录验证中...");
return "admin".equals(username) && "adminpass".equals(password);
}
}
public class OAuthLoginService implements LoginService {
@Override
public boolean login(String username, String token) {
System.out.println("OAuth 登录验证中...");
return "oauth_token".equals(token);
}
}
每个实现类各自处理自己的登录逻辑,互不干扰,职责单一。
3. 工厂类 LoginFactory
public class LoginFactory {
public static LoginService getLoginService(String userType) {
switch (userType.toLowerCase()) {
case "user":
return new UserLoginService();
case "admin":
return new AdminLoginService();
case "oauth":
return new OAuthLoginService();
default:
throw new IllegalArgumentException("未知用户类型: " + userType);
}
}
}
这个工厂类根据 userType
动态创建不同的登录对象。调用方无需知道这些类的具体细节,只要提供一个标识即可。
4. 客户端使用(Test 类)
这个客户端代码从头到尾都没有出现任何具体子类的名字,只跟接口 LoginService
打交道,完美体现了解耦。
public class Test {
public static void main(String[] args) {
String userType = "oauth";
String username = "admin";
String token = "oauth_token";
LoginService loginService = LoginFactory.getLoginService(userType);
boolean success = loginService.login(username, token);
System.out.println(success ? "登录成功!" : "登录失败!");
}
}
这个客户端代码从头到尾都没有出现任何具体子类的名字,只跟接口 LoginService
打交道,完美体现了解耦。
五、工厂模式进阶建议
在实际项目中,工厂模式可以结合以下设计理念使用:
策略模式:工厂只负责创建对象,具体逻辑交给策略执行
配置驱动工厂:通过配置文件动态注入类名,支持热插拔
反射 + 注册表:消除
switch
分支,提升扩展性
如果你想进一步封装登录逻辑,可以使用策略 + 工厂模式组合,写成:
LoginStrategy strategy = LoginStrategyFactory.get(userType);
strategy.authenticate(request);
完整代码:
package com.Factory_Pattern;
import java.util.HashMap;
import java.util.Map;
public class Final {
public static void main(String[] args) {
String userType = "oauth";
String username = "admin";
String credential = "oauth_token";
LoginStrategy strategy = LoginStrategyFactory.getStrategy(userType);
boolean success = strategy.login(username, credential);
System.out.println(success ? "✅ 登录成功!" : "❌ 登录失败!");
}
}
interface LoginStrategy {
boolean login(String username, String credential);
}
class UserLoginStrategy implements LoginStrategy {
@Override
public boolean login(String username, String password) {
System.out.println("【普通用户】登录验证...");
return "user".equals(username) && "123".equals(password);
}
}
class AdminLoginStrategy implements LoginStrategy {
@Override
public boolean login(String username, String password) {
System.out.println("【管理员】登录验证...");
return "admin".equals(username) && "adminpass".equals(password);
}
}
class OAuthLoginStrategy implements LoginStrategy {
@Override
public boolean login(String username, String token) {
System.out.println("【OAuth】登录验证...");
return "oauth_token".equals(token);
}
}
class LoginStrategyFactory {
private static final Map<String, LoginStrategy> STRATEGY_MAP = new HashMap<>();
static {
STRATEGY_MAP.put("user", new UserLoginStrategy());
STRATEGY_MAP.put("admin", new AdminLoginStrategy());
STRATEGY_MAP.put("oauth", new OAuthLoginStrategy());
}
public static LoginStrategy getStrategy(String userType) {
LoginStrategy strategy = STRATEGY_MAP.get(userType.toLowerCase());
if (strategy == null) {
throw new IllegalArgumentException("未知用户类型: " + userType);
}
return strategy;
}
}
六、结语
工厂模式作为 Java 最常用的设计模式之一,真正的精髓在于解耦与扩展性。尤其在业务不断演进、需求不断变化的环境中,工厂模式提供了一种优雅的应对方式。学会了工厂模式,你将能更从容地面对对象创建、逻辑分发和模块扩展等挑战。如果你觉得本文对你有帮助,欢迎点赞、评论和分享,让更多人了解并掌握设计模式的魅力!