资讯详情

设计模式实战:单例、工厂与策略模式解析

📅 2026/10/29 11:29:45 | 华诺云谱 👁 阅读
设计模式实战:单例、工厂与策略模式解析
1. 设计模式为何值得速通设计模式就像武侠小说中的招式套路是前人总结出来的最佳实践。我第一次接触设计模式是在2015年参与一个电商系统重构时当时面对错综复杂的订单处理逻辑我的导师指着代码说这里该用策略模式了。那次经历让我明白设计模式不是纸上谈兵的理论而是解决实际问题的利器。为什么设计模式能成为面试必问、项目必备的技能因为它们解决了软件开发中的三类核心问题对象创建难题如何优雅地创建对象单例确保全局唯一工厂隐藏创建细节建造者分步构造复杂对象。行为组织难题如何灵活定义算法族策略模式让算法可互换模板方法固定流程骨架。结构优化难题如何扩展功能而不改原有代码装饰者动态添加职责适配器兼容不同接口。提示设计模式不是银弹过度使用会导致代码过度设计。我的经验法则是当你在第三次写相似结构的代码时才考虑引入设计模式。2. 单例模式的正确打开方式2.1 饿汉式 vs 懒汉式单例模式最经典的实现争议。我曾在一个高并发系统中踩过坑用懒汉式导致订单号重复生成。来看两种实现对比// 饿汉式项目启动即加载 public class EagerSingleton { private static final EagerSingleton instance new EagerSingleton(); private EagerSingleton() {} public static EagerSingleton getInstance() { return instance; } } // 懒汉式用时加载 public class LazySingleton { private static volatile LazySingleton instance; private LazySingleton() {} public static LazySingleton getInstance() { if (instance null) { synchronized (LazySingleton.class) { if (instance null) { instance new LazySingleton(); } } } return instance; } }选择依据饿汉式适合初始化耗时短、必定会用的场景如配置加载懒汉式适合初始化耗时长、可能不用的场景如数据库连接池2.2 单例的现代实现在Java中更推荐使用枚举实现单例。这是我参与过的一个支付系统中采用的方案public enum PaymentGateway { INSTANCE; public void process(PaymentRequest request) { // 支付处理逻辑 } }这种写法天然防反射攻击且序列化安全。在Spring框架中默认的Bean作用域就是单例但要注意区分Spring单例每个容器内唯一设计模式单例JVM内唯一3. 工厂模式的三种段位3.1 简单工厂静态工厂适合对象创建逻辑简单的场景。比如我在物流系统中实现的运输工具工厂public class TransportFactory { public static Transport createTransport(String type) { switch (type) { case truck: return new Truck(); case ship: return new Ship(); default: throw new IllegalArgumentException(); } } }缺点新增类型需要修改工厂类违反开闭原则。3.2 工厂方法模式在开发跨平台UI框架时我们这样处理按钮创建public interface ButtonFactory { Button createButton(); } public class WindowsButtonFactory implements ButtonFactory { public Button createButton() { return new WindowsButton(); } } public class MacButtonFactory implements ButtonFactory { public Button createButton() { return new MacButton(); } }每个产品对应一个工厂符合开闭原则但会导致类爆炸。3.3 抽象工厂模式这是我为电商系统设计的跨数据库访问方案public interface DatabaseFactory { Connection createConnection(); QueryBuilder createQueryBuilder(); } public class MySQLFactory implements DatabaseFactory { public Connection createConnection() { return new MySQLConnection(); } public QueryBuilder createQueryBuilder() { return new MySQLQueryBuilder(); } }适合创建产品族的情况比如需要保证MySQL的Connection和QueryBuilder配套使用。4. 建造者模式的精妙之处4.1 传统实现方式在开发文档生成工具时我们这样构造PDF文档public class PdfDocumentBuilder { private String header; private String body; private String footer; public PdfDocumentBuilder setHeader(String header) { this.header header; return this; } public PdfDocumentBuilder setBody(String body) { this.body body; return this; } public PdfDocument build() { return new PdfDocument(header, body, footer); } }使用链式调用PdfDocument doc new PdfDocumentBuilder() .setHeader(合同) .setBody(条款内容...) .build();4.2 与工厂模式的区别关键差异在于工厂一次性创建完整对象建造者分步骤构造复杂对象我曾用建造者模式重构过一个游戏角色创建系统将原本需要20个参数的构造函数拆解成了清晰的步骤。5. 策略模式的实战应用5.1 电商促销场景在黑色星期五促销中我们实现了这样的价格策略系统public interface DiscountStrategy { double applyDiscount(double originalPrice); } public class ChristmasDiscount implements DiscountStrategy { public double applyDiscount(double originalPrice) { return originalPrice * 0.7; } } public class PriceCalculator { private DiscountStrategy strategy; public void setStrategy(DiscountStrategy strategy) { this.strategy strategy; } public double calculate(double price) { return strategy.applyDiscount(price); } }5.2 策略模式工厂模式在实际项目中我常将两者结合使用public class StrategyFactory { public static DiscountStrategy createStrategy(String season) { switch (season) { case christmas: return new ChristmasDiscount(); case blackfriday: return new BlackFridayDiscount(); default: return new NoDiscount(); } } }这样客户端代码只需DiscountStrategy strategy StrategyFactory.createStrategy(christmas); calculator.setStrategy(strategy);6. 模板方法模式的框架应用6.1 支付流程模板在开发支付网关时固定流程如下public abstract class PaymentProcessor { // 模板方法 public final void processPayment() { validate(); preProcess(); executePayment(); postProcess(); } protected abstract void validate(); protected abstract void executePayment(); protected void preProcess() { // 默认实现记录日志 } protected void postProcess() { // 默认实现发送通知 } }6.2 钩子方法的使用技巧在实现工作流引擎时我发现可以通过钩子方法增加灵活性public abstract class Workflow { public final void execute() { init(); doWork(); if (needAudit()) { audit(); } cleanup(); } protected boolean needAudit() { return true; // 默认需要审核 } }子类可以覆盖needAudit()来改变流程走向。这种技术在Spring的JdbcTemplate中大量使用。7. 设计模式的组合拳7.1 Spring中的模式混用以Spring MVC为例前端控制器是单例处理器映射使用策略模式视图解析器采用工厂方法拦截器链是责任链模式7.2 我的架构设计经验在微服务网关开发中我这样组合模式用建造者模式构造请求上下文用责任链模式处理过滤逻辑用策略模式选择路由算法用模板方法定义响应处理流程关键是要理解每个模式的适用场景而不是生搬硬套。我见过最糟糕的代码是一个简单工具类里用了5种设计模式结果没人能维护。8. 避免设计模式滥用8.1 反模式案例曾经review过一个过度设计的代码用抽象工厂创建只有一种实现的DAO用装饰者模式包装没有扩展需求的组件在不必要的场景使用观察者模式8.2 合理使用原则我的设计模式决策树这个变化点真的存在吗会有多个实现吗未来扩展的可能性有多大引入模式的复杂度是否值得记住KISS原则Keep It Simple, Stupid永远优先。当你在纠结该用哪种模式时很可能根本不需要用模式。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑