设计模式
设计模式常用的七大原则有:
1) 单一职责原则
2) 接口隔离原则
3) 依赖倒转原则 : 抽象不依赖细节,细节依赖抽象,相对于细节的多变性,抽象要稳定的多
继承给程序带来的侵入性,可移植性低,耦合性,父类修改对子类影响太大
4) 里氏替换原则 : ?
5) 开闭原则 ocp : 模块和函数应该对扩展开放(对提供方),对修改关闭(对使用方),软件修改的时候,尽量扩展,减少修改
6) 迪米特法则 : 最少知道原则,避免非直接关系的耦合
7) 合成复用原则 : 尽量使用合成聚合的方式,而不是继承
原型模式UML(工具:Rational Rose),原型模式的深浅拷贝,spring原型bean的的源码
状态模式(ifelse的维护状态的不可选取性)
解释器设计模式,Spring框架中SpelExpressionParser就使用到解释器模式
继承和实现的区别
设计模式分为三种类型,共23种
1) 创建型模式:单例模式、抽象工厂模式、原型模式、建造者模式、工厂模式。
2) 结构型模式:适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。
3) 行为型模式:模版方法模式、命令模式、访问者模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式(Interpreter模式)、状态模式、策略模式、职责链模式(责任链模式)。
一、单例模式 : 使用场景 - -> 频繁创建、销毁对象的类,数据源,session工厂等
Hibernate的SessionFactory,它充当数据存储源的代理,并负责创建Session对象。SessionFactory并不是轻量级的,一般情况下,一个项目通常只需要一个SessionFactory就够。
单例设计模式一共有8种写法,各种优缺点
1) 饿汉式 两种
2) 懒汉式 三种
3) 双重检查
4) 静态内部类
5) 枚举
1) 饿汉式(静态常量) : 线程安全,浪费内存
2) 饿汉式(静态代码块) : 同上
3) 懒汉式(线程不安全)
4) 懒汉式(线程安全,同步方法)
5) 懒汉式(线程安全,同步代码块) : 非空校验线程不安全
6) 双重检查 : 同步代码块中也做非空判断,推荐
7) 静态内部类 : single类的类加载机制,推荐
8) 枚举 : 防止反序列化重新创建新的对象
二、工厂模式 (依赖抽象原则)
简单工厂模式 : 简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例,定义了一个创建对象的类,由这个类来封装实例化对象的行为(代码)
工厂方法模式 : 定义了一个创建对象的抽象方法,由子类决定要实例化的类。工厂方法模式将对象的实例化推迟到子类。
抽象工厂模式 : 定义了一个interface用于创建相关或有依赖关系的对象簇,而无需指明具体的类
可以将简单工厂模式和工厂方法模式进行整合。
将工厂抽象成两层,AbsFactory(抽象工厂) 和 具体实现的工厂子类。程序员可以根据创建对象类型使用对应的工厂子类。这样将单个的简单工厂类变成了工厂簇,更利于代码的维护和扩展。
跟进一下calendar的源码
创建对象实例时,不要直接 new 类, 而是把这个new 类的动作放在一个工厂的方法中,并返回。
有的书上说,变量不要直接持有具体类的引用。
不要让类继承具体类,而是继承抽象类或者是实现interface(接口)不要覆盖基类中已经实现的方法。
三、原型模式
对对象进行重复创建的时候,获取属性再创建效率低
实现cloneable接口
spring创建prototype的bean
跟进cloneable的源码
四、建造者模式 : 将产品和产品建造的过程解耦
建造者模式的四个角色
1) Product(产品角色): 一个具体的产品对象。
2) Builder(抽象建造者): 创建一个Product对象的各个部件指定的 接口/抽象类。
3) ConcreteBuilder(具体建造者): 实现接口,构建和装配各个部件。
4) Director(指挥者): 构建一个使用Builder接口的对象。它主要是用于创建一个复杂的对象。它主要有两个作用,一是:隔离了客户与对象的生产过程,二是:负责控制产品对象的生产过程
StringBuilder的源码
符合开闭原则,但是产品之间的差异大、内部变化复杂导致需要很多的建造者来实现这种变化的这两种情况的时候,不建议使用建造者模式
抽象工厂模式VS建造者模式 : 前者是对产品家族的创建,是对不同维度的产品的组合,不需要关心产品构建的过程:后者是对产品的组装、构建的过程的设计
五、适配器模式(类,对象,接口),让原本不兼容的类可以兼容,adapter,src(适配者), dst(目标)
1. 类适配器:单继承中只能有一个适配者,dst只能是接口
2. 对象适配器:持有对象而非继承,该模式常用,使用成本低,更灵活
可以设计一个抽象类实现接口,选择性的覆盖需要的方法
3. 接口适配器 :
三者的区别 : 前者将src作为类继承,中间者将其作为一个对象持有,后者将其作为一个接口实现
六、桥接模式 : 将抽象和实现放在两个不同的类层次中,是两个层次可以独立改变,基于类的最小设计原则,保持各部分的独立性和功能的扩展性(对不用的类型进行一系列操作,后续新增的维护太复杂)
常见的应用场景:
-JDBC驱动程序
-银行转账系统
转账分类: 网上转账,柜台转账,AMT转账
转账用户类型:普通用户,银卡用户,金卡用户..
-消息管理
消息类型:即时消息,延时消息
消息分类:手机短信,邮件消息,QQ消息...
七、装饰者设计模式(不同的组合有不同的情况出现,比如订单系统,不同商品之间的组合有不同的处理方式)
FilterInputStream
八、组合模式
简化客户端操作,有较强的拓展性,方便创造出复杂的层次结构,对于需要遍历组织结构、或者处理的对象具有树形结构时,非常适合
HashMap使用了组合模式
九、外观模式,过程模式 : 将类中的调用进行高层的封装,是客户端的调用最简单化
对于一个功能,需要调用不同对象进行不同操作
MyBatis创建MateObject对象的时候使用到了外观模式
十、享元模式: 对于频繁创建对象的操作,使用缓存池进行操作,避免对象的重复创建和回收
注意事项:需要分离出内部状态和外部状态,其中外部状态具有固化特性,不应该随着内部状态的改变而改变
Integer中的享元模式,就是127之后128的比较,还有自动封装操作
十一、代理模式(为一个对象提供一个替身,以控制对这个对象的访问。即通过代理对象访问目标对象。代理的对象通常是远程对象、创建开销大的对象,需要安全控制的对象)
静态代理 : 目标对象实现接口,代理对象也实现接口,通过代理对象调用目标对象的方法(相同的接口,相同的方法),
优点:不修改目标对象
缺点:代理类多,维护复杂
动态代理(JDK代理,接口代理):只需要目标对象实现接口
cglib代理(在内存动态创建对象,不需要实现接口):不需要实现接口,底层使用字节码处理器ASM转换成字节码
类为final报错,illegalArgumentException
方法为final或者static,不会被拦截
常见的代理模式:
1) 防火墙代理
2) 缓存代理
3) 远程代理:远程对象的使用
4) 同步代理:多线程
十二、模板模式:子类重写抽象类的某些方法,执行的框架和主要的不变的方法还是在抽样类中
钩子方法:默认不执行任何操作,子类视情况覆盖
十三、命令模式:将动作的请求者和动作的执行者解耦(在执行者的)
spring中jdbcTemplate的使用
容易实现对请求的实现和撤销
可能导致某些系统有过多的具体命令类
命令模式经典的应用场景:
界面的一个按钮都是一条命令、
模拟CMD(DOS命令)订单的撤销/恢复、
触发-反馈机制
十四、访问者模式:需要对一个对象结构中的对象进行很多不同操作(这些操作彼此没有关联),同时需要避免让这些操作"污染"这些对象的类
适合做报表、UI、拦截器与过滤器,适用于数据结构相对稳定的系统
如果一个系统有比较稳定的数据结构,又有经常变化的功能需求,那么访问者模式就是比较合适的.
十五、迭代器模式
ArrayList的应用
缺点:每个聚合对象都需要一个迭代器
十六、观察者模式(通过注册、注销、通知方法,避免增加对象后,通知的时候需要修改代码)
JDK的Observe类
十七、中介者模式(用一个中介对象封装一系列的对象交互,MVC)
顺序执行时候的耦合性,彼此之间传递消息可能混乱,增加新的流程的维护性差
十八、备忘录模式(将对象的某个时刻的数据进行记录,可恢复)
new对象会暴露内部细节
消耗内存,可以和原型模式配合使用
十九、解释器模式
Spring框架中SpelExpressionParser
引起类膨胀,采用递归模式,效率低
二十、状态模式
它主要用来解决对象在多种状态转换时,需要对外输出不同的行为的问题。状态和行为是一一对应的,状态之间可以相互转换
状态过多会影响维护难度
二十一、策略模式
二十二、责任链模式(不同的情况下不同的人进行审批)
SpringMVC-HandlerExecutionChain 类就使用到职责链模式
事务
@SuppressWarnings的作用
https://www.cnblogs.com/yinhu/archive/2006/02/11/328862.htmlhttps://www.cnblogs.com/yinhu/archive/2006/02/11/328862.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构