设计模式
工厂方法模式(解耦):
简单工厂模式:
抽象产品:定义了产品的规范,描述了产品的特性和功能
具体产品:实现或继承抽象产品的子类
具体工厂:提供了创建产品的方法,调用者通过该方法来获取产品
开闭原创:扩展开放,对修改关闭
工厂方法模式:
工厂方法模式的主要角色:
- 抽象工厂(Abstract Factory):提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法来创建产品。
- 具体工厂(ConcreteFactory):主要是实现抽象工厂中的抽象方法,完成具体产品的创建。
- 抽象产品(Product):定义了产品的规范,描述了产品的主要特性和功能。
- 具体产品(ConcreteProduct):实现了抽象产品角色所定义的接口,由具体工厂来创建,它同具体工厂之间一一对应。
抽象工厂模式:
抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产一个等级的产品,而抽象工厂模式可生产多个等级的产品。
一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂
策略模式:
策略模式:
- 该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户
- 它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理
策略模式的主要角色如下:
- 抽象策略(Strategy)类:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。
- 具体策略(Concrete Strategy)类:实现了抽象策略定义的接口,提供具体的算法实现或行为。
- 环境(Context)类:持有一个策略类的引用,最终给客户端调用。
案例(策略+工厂):
- 订单的支付策略(支付宝、微信、银行卡…)
- 解析不同类型excel(xls格式、xlsx格式)
- 打折促销(满300元9折、满500元8折、满1000元7折…)
- 物流运费阶梯计算(5kg以下、5-10kg、10-20kg、20kg以上)
一句话总结:只要代码中有冗长的if-else或 switch 分支判断都可以采用策略模式优化
- 提供了很多种策略,都让spring容器管理
- 提供一个工厂:准备策略对象,根据参数提供对象
责任链模式:
概述:
为了避免请求的发送者与多个请求的处理者耦合在一起,将所有请求的处理者通过前一对象记住下一个对象的引用而连成的一条链;
当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止
责任链设计模式的主要角色:
- 抽象处理者(Handler)角色:定义一个处理请求的接口,包含抽象处理方法和一个后继连接。
- 具体处理者(Concrete Handler)角色:实现抽象处理者的处理方法,判断能否处理本次请求,如果可以处理请求则处理,否则将该请求转给它的后继者。
- 客户类(Client)角色:创建处理链,并向链头的具体处理者对象提交请求,它不关心处理细节和请求的传递过程。
责任链的优缺点:
优点:
- 降低了对象之间的耦合
- 增强了系统的可扩展性
- 增强了给对象指派职责的灵活性
- 责任链简化了对象之间的连接
- 责任分担
缺点:
- 对比较长的职责链,请求的处理可能涉及到多个对象,系统性能将受到一定影响
- 职责链建立的合理性要靠客户端来保证,增加了客户端的复杂性,可能会由于职责链的错误设置而导致系统出错,如可能会造成循环调用
使用场景:
单例:
概述:
单例设计模式是一种创建型设计模式,它确保一个类只有一个实例,并提供一个全局访问点来获取这个实例。
单例设计模式的特点
-
唯一实例:确保类在整个应用程序生命周期中只创建一个实例。
-
全局访问点:提供一个静态方法或属性,让其他代码可以访问这个唯一实例。
-
延迟初始化:实例通常在第一次使用时创建,而不是在应用程序启动时。
优点:
-
节省系统资源,避免重复创建和销毁对象。
-
提供全局访问点,简化代码结构。
缺点:
- 违反单一职责原则,一个类负责创建和管理自己的实例。
- 可能导致代码耦合度增加,难以测试和维护。
- 在多线程环境中需要特别注意线程安全问题。
单例设计模式的注意事项
- 在多线程环境中,确保实现是线程安全的。
- 考虑反序列化和反射可能破坏单例模式的情况。
- 谨慎使用单例模式,避免滥用导致代码结构僵化。
单例设计模式的应用场景
- 日志记录器:整个应用程序使用同一个日志记录实例,避免日志文件冲突。
- 配置管理器:全局管理应用程序的配置信息。
- 数据库连接池:共享数据库连接,提高性能。
- 线程池:管理一组工作线程,避免重复创建和销毁线程。
代理:
概述:
代理设计模式是一种结构型设计模式,它允许通过代理对象控制对另一个对象(即目标对象)的访问。代理对象在客户端和目标对象之间充当中间层,负责处理与访问控制、延迟加载、缓存等相关的任务,而不需要修改目标对象的代码。
代理设计模式的核心角色
- 抽象主题(Subject):定义了目标对象和代理对象的共同接口,客户端通过这个接口与目标对象或代理对象进行交互。
- 真实主题(Real Subject):实现了抽象主题接口的具体类,是代理对象所代表的真实对象,负责执行具体的业务逻辑。
- 代理(Proxy):也实现了抽象主题接口,持有一个对真实主题的引用,并在需要时将请求转发给真实主题。代理对象可以在转发请求前后添加额外的处理逻辑。
代理设计模式的应用场景
- 远程代理(Remote Proxy):为一个位于不同地址空间的对象提供本地代理,隐藏对象存在于不同地址空间的事实。例如,Web 服务中的 Stub 对象。
- 虚拟代理(Virtual Proxy):延迟创建开销较大的对象,直到真正需要使用它时才创建。例如,图片的懒加载。
- 保护代理(Protection Proxy):控制对原始对象的访问权限,根据访问者的身份决定是否允许访问。例如,访问敏感信息时的权限验证。
- 智能引用代理(Smart Reference Proxy):在访问对象时执行额外的操作,如引用计数、缓存、锁定等。例如,缓存频繁访问的对象。
代理设计模式的优缺点
优点:
- 符合开闭原则:可以在不修改目标对象的情况下,通过代理对象扩展功能。
- 降低耦合度:客户端与目标对象解耦,只需要通过接口与代理对象交互。
- 提供额外功能:代理对象可以在不改变目标对象的前提下,添加日志记录、权限控制、延迟加载等功能。
缺点:
- 增加系统复杂度:引入代理对象会使系统的类和对象数量增加,可能导致代码变得复杂。
- 可能影响性能:代理对象在转发请求时可能会增加额外的处理步骤,导致性能开销。