java常见设计模式介绍

常见设计模式介绍

原型模式

原型模式是指原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象。

适用场景
  1. 类初始化消耗资源较多
  2. 使用new生成一个对象需要非常烦琐的过程(数据准备、权限访问等)
  3. 构造函数比较复杂
  4. 在循环体中产生大量对象
运用场景

Spring中 scope = "prototype",以及JSON.parseObject()也是原型模式

代理模式

代理模式在客户端与目标对象之间起到中介作用,代理模式属于结构型设计模式。使用代理模式主要有两个目的:一是保护目标对象,二是增强目标对象。

代理分为:静态代理、动态代理、CGLib代理

CGLib 和 JDK 动态代理对比
  1. JDK 动态代理实现了被代理对象的接口, CGLib 代理继承了被代理对象 。
  2. JDK 动态代理和 CGLib 代理都在运行期生成字节码,JDK 动态代理直接写 Class 字节码, CG Lib 代理使用 ASM 框架 写Class 字节码, CGlib 代理实现更复杂,生成代理类比 JDK 动态代理效率低
  3. JDK 动态代理调用代理方法是通过反射机制调用的, CGLib 代理是通过 FastClass 机制 直接调用方法的, CGLib 代理的执行效率更高。
Spring 中的代理选择原则
  1. 当 Bean 有实现接口时, Spring 就会用 JDK 动态代理。
  2. 当 Bean 没有实现接口时, Spring 会选择 CGLib 代理。
静态代理和动态代理的本质区别
  1. 静态代理只能通过于动完成代理操作,如果被代理类增加了新的方法,代理类需要同步增加,违背开闭原则。
  2. 动态代理采用在运行时动态生成代码的方式,取消了对被代理类的扩展限制,遵循开闭原则。
  3. 若动态代理要对目标类的增强逻辑进行扩展,结合策略模式,只需要新增策略类便可完成,无须修改代理类的代码。
代理模式的优缺点

优点:

  1. 代理模式能将代理对象与真实被调用目标对象分离。
  2. 在一定程度上降低了系统的耦合性,扩展性好。
  3. 可以起到保护目标对象的作用。
  4. 可以增强目标对象的功能。

缺点:

  1. 代理模式会造成系统设计中类的数量增加。
  2. 在客户端和目标对象中增加一个代理对象,会导致请求处理速度变慢。
  3. 增加了系统的复杂度。

委派模式

委派模式( Delegate Pattern )不属于 GoF 23 种设计模式。委派模式的基本作用就是负责任务的调用和分配,跟代理模式很像,可以看作一种特殊情况下的静态的全权代理,但是代理模式注重过程,而委派模式注重结果。

代理模式、委托模式、策略模式之间区别
  1. 代理模式注重 是过程 委派模式注重的是结果

  2. 策略模式注重可扩展性(外部扩展性),委派模式注重内部的灵活性和可复用性

  3. 委派模式的核心就是分发、调度、派遣,委派模式是静态代理和策略模式的一种特殊组合

策略模式

策略模式( Strategy Pattern )是指定义了算法家族并分别封装起来,让它们之间可以互相替换,此模式使得算法的变化不会影响使用算法的用户。

应用场景
  1. 系统中有很多类,而它们的区别仅仅在于行为不同。
  2. 一个系统需要动态地在几种算法中选择一种。
运用场景

JDK的Comparator接口中的 compare()方法就是一个策略模式的抽象实现。

策略模式的优缺点

优点:

  1. 策略模式符合开闭原则。
  2. 策略模式可避免使用多重条件语句,如 if… else 语句、 switch 语句。
  3. 使用策略模式可以提高算法的保密性和安全性。

缺点:

  1. 客户端必须知道所有的策略,并且自行决定使用哪一个策略类。
  2. 代码中会产生非常多的策略类,增加了代码的维护难度。

模板模式

模板模式又叫模板方法模式(Template Method Pattern),是指定义一个算法的骨架,并允许子类为一个或者多个步骤提供实现 。模板模式使得子类可以在不改变算法结构的情况下,重新定义算法的某些步骤,属于行为型设计模式。

如:炒菜流程:洗菜–刷锅–点火–放油–放材料–炒菜,其中某些步骤可以固定不改变,但是流程是一样的。

适用场景
  1. 一次性实现一个算法的不变部分,并将可变的行为留给子类来实现。
  2. 各子类中公共的行为被提取出来并集中到一个公共的父类中,从而避免代码重复。
模板模式的优缺点

优点:

  1. 利用模板模式将相同处理逻辑的代码放到抽象父类中,可以提高代码的复用性。
  2. 将不同的代码放到不同的子类中,通过对子类的扩展增加新的行为,可以提高代码的扩展性。
  3. 把不变的行为写在父类中,去除子类的重复代码 ,提供了一个很好的代码复用平台 ,符合开闭原则。

缺点:

  1. 每个抽象类都需要一个子类来实现,导致了类的数量增加。
  2. 类数量的增加间接地增加了系统的复杂性。
  3. 因为继承关系自身的缺点,如果父类添加新的抽象方法,所有子类都要改一遍。

适配器模式

适配器模式( Adapter Pattern )是指将一个类的接口转换成用户期望的另一个接口,使原本接口不兼容的类可以一起工作,属于结构型设计模式。

应用场景
  1. 已经存在的类的方法和需求不匹配(方法结果相同或相似)的情况。
  2. 适配器模式不是软件初始阶段考虑的设计模式,是随着软件的发展,由于不同产品、不同厂家造成功能类似而接口不同的问题的解决方案,有点亡羊补牢的感觉。
适配器模式的优缺点

优点:

  1. 能提高类的透明性和复用性,现有的类会被复用但不需要改变。
  2. 目标类和适配器类解稿,可以提高程序的扩展性。
  3. 在很多业务场景中符合开闭原则。

缺点:

  1. 在适配器代码编写过程中需要进行全面考虑 ,可能会增加系统的复杂性。
  2. 增加了代码的阅读难度,降低了代码的可读性,过多使用适配器会使系统的代码变得凌乱。

装饰者模式

装饰者模式( Decorator Pattern )是指在不改变原有对象的基础上,将功能附加到对象上,提 供了比继承更有弹性的方案(扩展原有对象的功能),属于结构型模式。装饰者模式在生活中的应用也比较多,如给煎饼加鸡蛋、给蛋糕加 些水果、给房子装修等,都是在为对象扩展一些额外的职责。

适用场景
  1. 扩展一个类的功能或给一个类添加附加职责。
  2. 动态给一个对象添加功能,这些功能可以再动态地撤销。
装饰者模式和适配器模式对比

装饰者模式和适配器模式都是包装模式(Wrapper Pattern),装饰者模式也是一种特殊的代理模式。

装饰者模式适配器模式
形式是一种非常特别的适配器模式没有层级关系,装饰者模式有层级关系
定义装饰者和被装饰者实现同一个接口,主要目的是扩展后依旧保留OOP关系适配器和被适配者没有必然的联系,通常采用继承或代理的形式进行包装
关系满足is-a关系满足has-a的关系
功能注重覆盖、扩展注重兼容、转换
设计前置考虑后置考虑
装饰者模式的优缺点

优点:

  1. 装饰者模式是继承的有力补充,且比继承灵活,可以在不改变原有对象的情况下动态地给一个对象扩展功能,即插即用。
  2. 使用不同的装饰类及这些装饰类的排列组合,可以实现不同的效果。
  3. 装饰者模式完全符合开闭原则。

缺点:

  1. 会出现更多的代码、更多的类,增加程序的复杂性。
  2. 动态装饰时,多层装饰会更复杂。

观察者模式

应用场景

观察者模式( Observer Pattern )定义了对象之间的一对多依赖,让多个观察者对象同时监听一个主体象,当主体对象发生变化时,它的所有依赖者(观察者)都会收到通知井更新,属于行为型模式。观察者模式有时也叫作发布订阅模式 观察者模式主要用于在关联行为之间建立一套触发机制的场景。观察者模式在现实生活应用得也非常广泛,比如微信朋友圈动态通知、邮件通知、广播通知等。

观察者模式的优缺点

优点:

  1. 在观察者和被观察者之间建立了一个抽象的耦合。
  2. 观察者模式支持广播通信。

缺点:

  1. 观察者之间有过多的细节依赖、时间消耗多,程序的复杂性更高。
  2. 使用不当会出现循环调用。

各种设计模式的总结与对比

GoF 23种设计模式

设计模式其实是一门艺术。设计模式来源于生活,不要为了套用设计模式而使用设计模式 设计模式是在我们迷茫时提供的一种解决问题的方案,或者说用好设计模式可以防范于未然。

设计模式是经验之谈,总结的是前人的经验,提供给后人借鉴使用, 正所谓: “前人栽树, 后人乘凉。”设计模式可以帮助我们提升代码的可读性、可扩展性,降低维护成本,解决复杂的 业务问题,但是千万不要死记硬背,生搬硬套。

GoF 23种设计模式的归纳和总结
分类设计模式
创建型工厂方法模式、抽象工厂模式、建造者模式、原型模式、单例模式
结构型适配器模式、桥接模式、组合模式、装饰者模式、门面模式、享元模式、代理模式
行为型解释器模式、模板方法模式(模板模式〕、责任链模式、命令模式、法代器模式、调解者模式、 备忘录模式、观察者模式、状态模式、策略模式、访问者模式
设计模式之间的关联关系
单例模式和工厂模式

在实际业务代码中,通常会把工厂类设计为单例模式。

策略模式和工厂模式
  1. 工厂模式包含工厂方法模式和抽象工厂模式,是创建型模式,策略模式属于行为型模式。
  2. 工厂模式的主要目的是封装好创建逻辑,策略模式接收工厂创建好的对象,从而实现不同的行为。
策略模式和委派模式
  1. 策略模式是委派模式内部的一种实现形式,策略模式关注结果是否能互相替代。
  2. 委派模式更关注分发和调度的过程。
模板方法模式和工厂方法模式

工厂方法模式是模板方法模式的一种特殊实现,工厂方法模式相当于只有一个步骤的模板方法模式。

模板方法模式和策略模式
  1. 模板方法模式和策略模式都有封装算法。
  2. 策略模式使不同算法可以相互替换,且不影响客户端应用层的使用。
  3. 模板方法模式针对定义一个算法的流程,将一些有细微差异的部分交给子类实现。
  4. 模板方法模式不能改变算法流程,策略模式可以改变算法流程且可替换。策略模式通常用来替换if…else等条件分支语句。
装饰者模式和代理模式
  1. 装饰者模式的关注点在于给对象动态添加方法,而代理模式更加注重控制对象的访问。
  2. 代理模式通常会在代理类中创建被代理对象的实例,而装饰者模式通常会把被装饰者作为构造参数。
  3. 装饰者和代理者虽然都持有对方的引用,但处理重心是不一样的。
装饰者模式和适配器模式
  1. 装饰者模式和适配器模式都属于包装器模式(Wrapper Pattern)。
  2. 装饰者模式可以实现与被装饰者相同的接口,或者继承被装饰者作为它的子类,而适配器和被适配者可以实现不同的接口。
  3. 适配器模式主要解决兼容问题,不一定要统一父类。装饰者模式需要满足OOP的is-a的关系。
适配器模式和静态代理模式

适配器模式可以结合静态代理模式来实现,保存被适配对象的引用,但不是唯一的实现方式。

适配器模式和策略模式

在业务复杂的情况下,可利用策略模式优化适配器模式。

模式都属于包装器模式(Wrapper Pattern)。
2. 装饰者模式可以实现与被装饰者相同的接口,或者继承被装饰者作为它的子类,而适配器和被适配者可以实现不同的接口。
3. 适配器模式主要解决兼容问题,不一定要统一父类。装饰者模式需要满足OOP的is-a的关系。

适配器模式和静态代理模式

适配器模式可以结合静态代理模式来实现,保存被适配对象的引用,但不是唯一的实现方式。

适配器模式和策略模式

在业务复杂的情况下,可利用策略模式优化适配器模式。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值