23种设计模式精讲:从入门到精通,一文掌握设计模式核心思想
面试中经常被问到设计模式项目中不知道如何应用设计模式优化代码面对复杂系统设计感到无从下手本文全面讲解23种GoF设计模式包括6大设计原则、5种创建型模式、7种结构型模式、11种行为型模式结合UML类图、源码解析和实战案例助你成为架构设计高手轻松应对大厂面试 文章目录一、设计模式概述1.1 代码质量评价标准1.2 编程方法论1.3 设计模式分类二、UML类图三、六大设计原则SOLID四、创建型模式5种4.1 单例模式4.2 工厂方法模式4.3 抽象工厂模式4.4 建造者模式4.5 原型模式五、结构型模式7种5.1 代理模式5.2 桥接模式5.3 装饰者模式5.4 适配器模式5.5 门面模式5.6 组合模式5.7 享元模式六、行为型模式11种七、设计模式速查表一、设计模式概述1.1 代码质量评价标准设计模式的目标提高代码质量写出可维护、可扩展、可读性强的高质量代码。评价标准说明重要性可维护性不破坏原有设计、不引入新Bug的前提下快速修改代码⭐⭐⭐⭐⭐可读性代码易于理解和审查Code Review⭐⭐⭐⭐⭐可扩展性对修改关闭对扩展开放⭐⭐⭐⭐⭐灵活性代码能够灵活接纳新功能⭐⭐⭐⭐简洁性遵循KISS原则简单优雅⭐⭐⭐⭐可复用性减少重复代码DRY原则⭐⭐⭐⭐可测试性易于编写单元测试⭐⭐⭐⭐1.2 编程方法论提升代码质量的完整体系面向对象设计基础 ↓ 设计原则指导思想 ↓ 设计模式原则的具体实现 ↓ 编程规范提高可读性 ↓ 重构技巧持续优化六大设计原则SOLID原则英文缩写核心思想单一职责原则SRP一个类只负责一个职责开闭原则OCP对扩展开放对修改关闭里氏替换原则LSP子类可以替换父类接口隔离原则ISP接口要小而专依赖倒置原则DIP依赖抽象而非具体实现迪米特法则LoD最少知识原则1.3 设计模式分类GoFGang of Four23种设计模式分为三大类类型数量常用模式创建型模式5种单例、工厂方法、抽象工厂、建造者结构型模式7种代理、装饰者、适配器、桥接行为型模式11种观察者、策略、模板、职责链二、UML类图2.1 类图表示法符号含义Java对应public公共访问-private私有访问#protected受保护访问2.2 类之间的关系关系图示代码示例耦合度实现虚线空心三角implements低泛化继承实线空心三角extends高关联实线箭头成员变量中聚合实线空心菱形构造器传入中组合实线实心菱形内部创建高依赖虚线箭头方法参数低编程建议多用组合少用继承三、六大设计原则SOLID3.1 单一职责原则SRP定义一个类或模块只负责完成一个职责。核心思想不要设计大而全的类要设计粒度小、功能单一的类。判断标准类中的代码行数、函数过多类依赖的其他类过多私有方法过多大量方法集中操作几个属性3.2 开闭原则OCP⭐最重要定义对扩展开放对修改关闭。实现方式通过接口或抽象类定义稳定的行为通过具体实现类来扩展功能示例// 抽象接口 - 稳定publicinterfaceIStrategy{doublerealPrice(doubleconsumePrice);}// 具体实现 - 可扩展publicclassPromotionalStrategyimplementsIStrategy{publicdoublerealPrice(doubleconsumePrice){if(consumePrice200){return200(consumePrice-200)*0.8;}returnconsumePrice;}}publicclassRebateStrategyimplementsIStrategy{publicdoublerealPrice(doubleconsumePrice){returnconsumePrice*0.8;}}3.3 里氏替换原则LSP定义子类对象能够替换程序中父类对象出现的任何地方并且保证程序逻辑行为不变。核心子类可以扩展父类功能但不能改变父类原有功能。3.4 接口隔离原则ISP定义客户端不应该被迫依赖于它不使用的方法。与单一职责原则的区别单一职责原则约束的是类接口隔离原则约束的是接口3.5 依赖倒置原则DIP定义高层模块不应该依赖低层模块两者都应该依赖抽象抽象不应该依赖细节细节应该依赖抽象实现方式面向接口编程3.6 迪米特法则LoD定义最少知识原则talk only to your immediate friends只和你最亲密的朋友交谈。核心降低类之间的耦合度。四、创建型模式5种创建型模式提供创建对象的机制提升已有代码的灵活性和复用性。4.1 单例模式 ⭐⭐⭐⭐⭐定义保证一个类在运行期间只有一个实例对外提供服务。实现方式对比实现方式线程安全懒加载性能推荐度饿汉式✅❌高⭐⭐⭐懒汉式线程不安全❌✅高⭐懒汉式synchronized✅✅低⭐⭐双重检测✅✅高⭐⭐⭐⭐静态内部类✅✅高⭐⭐⭐⭐枚举✅✅高⭐⭐⭐⭐⭐双重检测实现publicclassSingleton{// volatile保证可见性和禁止指令重排privatevolatilestaticSingletoninstancenull;privateSingleton(){}publicstaticSingletongetInstance(){// 第一次检查避免不必要的同步if(instancenull){synchronized(Singleton.class){// 第二次检查保证线程安全if(instancenull){instancenewSingleton();}}}returninstance;}}枚举实现推荐publicenumSingleton{INSTANCE;publicvoiddoSomething(){// 业务逻辑}}// 使用Singleton.INSTANCE.doSomething();4.2 工厂方法模式 ⭐⭐⭐⭐定义定义一个创建对象的接口让子类决定实例化哪个产品类对象。角色抽象工厂Abstract Factory具体工厂Concrete Factory抽象产品Abstract Product具体产品Concrete Product示例// 抽象产品publicinterfaceIFreeGoods{ResponseResultsendFreeGoods(AwardInfoawardInfo);}// 具体产品publicclassDiscountFreeGoodsimplementsIFreeGoods{OverridepublicResponseResultsendFreeGoods(AwardInfoawardInfo){System.out.println(发放打折券);returnnewResponseResult(200,成功);}}// 抽象工厂publicinterfaceFreeGoodsFactory{IFreeGoodsgetInstance();}// 具体工厂publicclassDiscountFreeGoodsFactoryimplementsFreeGoodsFactory{OverridepublicIFreeGoodsgetInstance(){returnnewDiscountFreeGoods();}}4.3 抽象工厂模式定义提供一个创建一系列相关或相互依赖对象的接口而无须指定它们具体的类。与工厂方法的区别工厂方法创建单一产品抽象工厂创建产品族一系列相关产品适用场景需要创建的产品系列有较多共性特征需要解决跨平台兼容性问题4.4 建造者模式 ⭐⭐⭐⭐定义将一个复杂对象的构建与表示分离使得同样的构建过程可以创建不同的表示。适用场景类的构造函数参数过多超过4个需要创建不可变对象链式调用实现publicclassRabbitMQClient{privateStringhost;privateintport;privateStringqueue;privateRabbitMQClient(Builderbuilder){this.hostbuilder.host;this.portbuilder.port;this.queuebuilder.queue;}publicstaticclassBuilder{privateStringhost127.0.0.1;privateintport5672;privateStringqueue;publicBuildersetHost(Stringhost){this.hosthost;returnthis;}publicBuildersetPort(intport){this.portport;returnthis;}publicBuildersetQueue(Stringqueue){this.queuequeue;returnthis;}publicRabbitMQClientbuild(){// 参数校验if(queuenull){thrownewRuntimeException(队列名称不能为空);}returnnewRabbitMQClient(this);}}}// 使用RabbitMQClientclientnewRabbitMQClient.Builder().setHost(192.168.1.1).setPort(5672).setQueue(order_queue).build();4.5 原型模式定义用已创建的实例作为原型通过复制该原型对象来创建一个和原型相同的新对象。适用场景对象创建成本大复杂计算、IO操作需要保存对象状态撤销操作深克隆 vs 浅克隆类型基本数据类型引用类型实现方式浅克隆复制值复制引用clone()深克隆复制值复制对象序列化/递归clone深克隆实现publicclassConcretePrototypeimplementsCloneable,Serializable{privatePersonperson;// 浅克隆OverrideprotectedConcretePrototypeclone()throwsCloneNotSupportedException{return(ConcretePrototype)super.clone();}// 深克隆推荐publicConcretePrototypedeepClone()throwsException{ByteArrayOutputStreambosnewByteArrayOutputStream();ObjectOutputStreamoosnewObjectOutputStream(bos);oos.writeObject(this);ByteArrayInputStreambisnewByteArrayInputStream(bos.toByteArray());ObjectInputStreamoisnewObjectInputStream(bis);return(ConcretePrototype)ois.readObject();}}五、结构型模式7种结构型模式总结类和对象组合在一起的经典结构。5.1 代理模式 ⭐⭐⭐⭐⭐定义为其他对象提供一种代理以控制对这个对象的访问。三种实现方式实现方式特点适用场景静态代理编译时确定需手动编写代理类简单场景JDK动态代理基于接口运行时生成有接口的场景CGLIB动态代理基于继承可代理普通类无接口的场景JDK动态代理示例publicclassProxyFactory{privateObjecttarget;publicProxyFactory(Objecttarget){this.targettarget;}publicObjectgetProxyInstance(){returnProxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),(proxy,method,args)-{System.out.println(前置增强);Objectresultmethod.invoke(target,args);System.out.println(后置增强);returnresult;});}}应用场景远程代理RPC调用虚拟代理延迟加载保护代理权限控制智能引用引用计数5.2 桥接模式定义将抽象部分与它的实现部分分离使它们都可以独立地变化。核心思想用组合替代继承避免类爆炸。示例支付系统支付渠道 × 支付方式支付渠道微信、支付宝 ↓ 组合 支付方式密码、人脸、指纹5.3 装饰者模式定义动态地给一个对象添加一些额外的职责。特点比继承更灵活可以动态添加/移除功能符合开闭原则经典应用Java IO流// 层层包装动态添加功能InputStreamisnewFileInputStream(test.txt);BufferedInputStreambisnewBufferedInputStream(is);DataInputStreamdisnewDataInputStream(bis);5.4 适配器模式定义将一个类的接口转换成客户希望的另外一个接口。两种实现类适配器通过继承实现对象适配器通过组合实现推荐应用场景接口不兼容复用旧代码统一多个类的接口5.5 门面模式外观模式定义为子系统中的一组接口提供一个一致的界面。作用简化客户端调用降低耦合度分层架构的入口5.6 组合模式定义将对象组合成树形结构以表示部分-整体的层次结构。适用场景树形结构场景统一处理叶子节点和容器经典应用文件系统、组织架构5.7 享元模式定义运用共享技术有效地支持大量细粒度的对象。核心思想复用对象减少内存占用。经典应用Java字符串常量池数据库连接池线程池六、行为型模式11种行为型模式负责对象间的高效沟通和职责传递委派。模式定义应用场景观察者模式定义对象间的一对多依赖关系事件监听、消息订阅模板方法模式定义算法骨架子类实现步骤框架设计、流程控制策略模式定义算法族分别封装起来支付方式、排序算法职责链模式将请求的发送者和接收者解耦审批流程、过滤器链迭代器模式提供一种方法顺序访问聚合对象集合遍历状态模式允许对象在内部状态改变时改变行为订单状态、游戏状态命令模式将请求封装为对象撤销/重做、队列请求备忘录模式在不破坏封装性的前提下捕获对象状态撤销操作、游戏存档访问者模式将数据结构与操作分离编译器、报表生成中介者模式定义一个中介对象来封装一系列对象交互聊天室、MVC控制器解释器模式为语言创建解释器正则表达式、SQL解析6.1 观察者模式 ⭐⭐⭐⭐⭐定义定义对象间的一对多依赖关系当一个对象状态改变时所有依赖于它的对象都得到通知并被自动更新。经典应用Java的Observable和ObserverSpring事件监听机制消息队列MQ6.2 模板方法模式 ⭐⭐⭐⭐定义定义一个操作中的算法骨架而将一些步骤延迟到子类中。经典应用Spring的JdbcTemplateServlet的doGet/doPost6.3 策略模式 ⭐⭐⭐⭐⭐定义定义算法族分别封装起来让它们可以互相替换。经典应用Java的Comparator接口Spring的Resource加载策略七、设计模式速查表7.1 设计原则速查原则口诀关键词SRP一类一职责粒度、内聚OCP对扩展开放抽象、接口LSP子类可替换继承、多态ISP接口要分离最小化、专注DIP依赖抽象接口编程LoD最少知道解耦、中介7.2 设计模式速查类型模式核心思想记忆口诀创建型单例全局唯一一夫一妻创建型工厂方法子类决定实例各司其职创建型抽象工厂创建产品族家族企业创建型建造者分步骤构建步步为营创建型原型复制创建克隆自己结构型代理控制访问找代理人结构型装饰者动态增强锦上添花结构型适配器接口转换转换插头结构型桥接组合代替继承桥接两岸结构型门面统一入口门面担当结构型组合树形结构整体部分结构型享元共享复用共享资源行为型观察者订阅通知一呼百应行为型策略算法替换随机应变行为型模板方法骨架实现按部就班行为型职责链链式处理层层上报7.3 面试高频题单例模式的线程安全实现双重检测、静态内部类、枚举工厂模式与建造者模式的区别JDK动态代理与CGLIB动态代理的区别Spring中使用了哪些设计模式浅克隆与深克隆的区别及实现总结本文系统讲解了23种GoF设计模式六大设计原则SOLID单一职责、开闭、里氏替换、接口隔离、依赖倒置、迪米特法则创建型模式5种单例、工厂方法、抽象工厂、建造者、原型结构型模式7种代理、桥接、装饰者、适配器、门面、组合、享元行为型模式11种观察者、模板方法、策略、职责链、迭代器、状态、命令、备忘录、访问者、中介者、解释器学习建议先理解设计原则再学习设计模式结合实际项目在实践中应用阅读优秀框架源码Spring、JDK不要过度设计简单问题简单解决设计模式是内功不是招式。掌握设计思想比记忆具体实现更重要。关键词设计模式, GoF, 单例模式, 工厂模式, 代理模式, 观察者模式, 策略模式, 建造者模式, SOLID原则, UML类图如果本文对你有帮助欢迎点赞、收藏、关注有任何设计模式相关问题欢迎在评论区留言讨论。