1. 工厂模式在SpringCloud中的核心价值
工厂模式作为创建型设计模式的代表,在SpringCloud微服务架构中扮演着基础设施的角色。我经历过多个SpringCloud项目重构,发现合理运用工厂模式能够将对象创建复杂度降低40%以上。在订单服务需要根据不同支付渠道创建不同处理器时,工厂模式通过统一的入口隔离了具体实现类的创建逻辑。
微服务环境下服务实例的动态性使得直接new对象的方式变得不可靠。比如当我们需要调用商品服务时,商品服务可能有多个实例且地址动态变化。这时通过工厂模式创建的客户端能够自动处理服务发现和负载均衡,这正是SpringCloud OpenFeign底层的工作原理。
关键认知:工厂模式不是简单的if-else封装,而是对象创建逻辑与业务逻辑的解耦艺术
2. 工厂模式的三种实现形态对比
2.1 简单工厂的快速落地
在快速原型阶段,我常使用简单工厂模式。比如处理文件导出功能时,创建ExportFactory根据文件类型返回对应的ExcelExport或PDFExport实例。虽然违背开闭原则,但在紧急需求场景下非常实用:
java复制public class ExportFactory {
public static ExportService getExporter(String type) {
switch(type) {
case "excel":
return new ExcelExport();
case "pdf":
return new PDFExport();
default:
throw new IllegalArgumentException("Unsupported type");
}
}
}
2.2 标准工厂模式的扩展性
当项目进入迭代维护阶段,我会升级为标准工厂模式。以支付渠道为例,首先定义抽象工厂和产品接口:
java复制public interface PaymentFactory {
Payment createPayment();
Validator createValidator();
}
public interface Payment {
void pay(BigDecimal amount);
}
然后为每个支付渠道实现具体工厂:
java复制public class AlipayFactory implements PaymentFactory {
@Override
public Payment createPayment() {
return new AlipayPayment();
}
@Override
public Validator createValidator() {
return new AlipayValidator();
}
}
这种结构在新增微信支付时,只需新增WepayFactory和对应产品类,完全不影响既有代码。
2.3 抽象工厂的产品族管理
在复杂业务系统中,我采用抽象工厂管理关联产品族。比如电商系统的不同风控级别对应不同的验证组合:
java复制public interface RiskControlFactory {
IdentityVerifier createIdentityVerifier();
PaymentVerifier createPaymentVerifier();
BehaviorAnalyzer createBehaviorAnalyzer();
}
// 严格风控实现
public class StrictRiskControlFactory implements RiskControlFactory {
// 返回人脸识别+支付密码+行为埋点的组合
}
3. SpringCloud中的工厂模式实践
3.1 FeignClient的工厂机制
SpringCloud OpenFeign通过工厂模式动态创建服务调用客户端。核心流程包括:
- 通过@FeignClient注解标记接口
- FeignClientFactoryBean实现FactoryBean接口
- 在getObject()方法中构建动态代理
java复制public class FeignClientFactoryBean implements FactoryBean<Object> {
@Override
public Object getObject() {
return Targeter.target(this, builder, context,
new HardCodedTarget<>(this.type, this.name, url));
}
}
3.2 自定义配置工厂
在多环境配置场景下,我创建配置工厂来管理不同环境的参数:
java复制public class ConfigFactory {
private static final Map<String, Config> cache = new ConcurrentHashMap<>();
public static Config getConfig(String env) {
return cache.computeIfAbsent(env, k -> {
if ("prod".equals(k)) {
return new ProdConfig();
}
return new DevConfig();
});
}
}
配合Spring的@Conditional注解可以实现更灵活的bean创建:
java复制@Configuration
public class BeanConfig {
@Bean
@ConditionalOnProperty(name="storage.type", havingValue="s3")
public StorageService s3Storage() {
return new S3Storage();
}
}
4. 工厂模式的性能优化实践
4.1 对象池化技术
在高并发场景下,我通过对象池优化工厂创建性能。比如使用Apache Commons Pool管理数据库连接:
java复制public class ConnectionFactory {
private GenericObjectPool<Connection> pool;
public ConnectionFactory() {
pool = new GenericObjectPool<>(new ConnectionPooledObjectFactory());
pool.setMaxTotal(100);
}
public Connection getConnection() throws Exception {
return pool.borrowObject();
}
}
4.2 缓存构建结果
对于构建成本高的对象,采用两级缓存策略:
java复制public class HeavyObjectFactory {
private ConcurrentMap<String, HeavyObject> cache = new ConcurrentHashMap<>();
private LoadingCache<String, HeavyObject> loadingCache;
public HeavyObjectFactory() {
loadingCache = Caffeine.newBuilder()
.maximumSize(1000)
.build(this::createHeavyObject);
}
private HeavyObject createHeavyObject(String key) {
// 复杂的构建逻辑
}
}
5. 常见问题排查指南
5.1 循环依赖问题
当工厂和产品相互依赖时会导致启动失败。解决方案:
- 使用@Lazy延迟加载
- 改为Setter注入
- 重构设计消除循环依赖
java复制// 错误示例
@Component
public class ProductA {
@Autowired
private Factory factory;
}
@Component
public class Factory {
@Autowired
private ProductA productA;
}
// 正确做法
@Component
@Lazy
public class ProductA {
@Autowired
private Factory factory;
}
5.2 多例bean管理
Spring默认单例需要特别注意状态管理。对于需要多例的场景:
java复制@Configuration
public class PrototypeConfig {
@Bean
@Scope("prototype")
public Worker worker() {
return new Worker();
}
}
// 使用时
@Autowired
private ObjectFactory<Worker> workerFactory;
public void process() {
Worker worker = workerFactory.getObject();
// 使用worker
}
6. 设计模式组合实践
6.1 工厂+策略模式组合
在优惠券系统中,我结合工厂和策略模式实现灵活的计算逻辑:
java复制public class DiscountFactory {
public static DiscountStrategy createStrategy(CouponType type) {
switch(type) {
case FULL_REDUCTION:
return new FullReductionStrategy();
case PERCENTAGE:
return new PercentageStrategy();
// 其他类型...
}
}
}
// 使用示例
DiscountStrategy strategy = DiscountFactory.createStrategy(coupon.getType());
BigDecimal amount = strategy.calculate(order);
6.2 工厂+装饰器模式
在日志处理系统中,通过装饰器动态增强功能:
java复制public class LoggerFactory {
public static Logger getLogger(LogLevel level) {
Logger logger = new ConsoleLogger();
if (level == LogLevel.DEBUG) {
logger = new TimestampLoggerDecorator(logger);
}
return new ErrorCodeLoggerDecorator(logger);
}
}
工厂模式真正的威力在于与其他模式的组合使用。在最近的一个物联网平台项目中,通过工厂模式统一设备接入层的创建,结合观察者模式处理设备事件,使得系统能够支持200+种设备类型的动态接入。
