Java23种设计模式
设计模式总体分类:
- 创建型模式(5种):单例模式、原型模式、工厂模式、抽象工厂模式、建造者模式
- 结构型模式(7种):代理模式、适配器模式、桥接模式、装饰者模式、外观模式、享元模式、组合模式
- 行为型模式(11种):模板方法模式、策略模式、命令模式、职责链模式、状态模式、观察者模式、中介者模式、迭代器模式、访问者模式、备忘录模式、解释器模式
软件设计原则概述
- 开闭原则:对扩展开放,对修改关闭。
- 里氏代换原则:子类继承父类时,除添加新的方法完成新的功能外,尽量不要重写父类的方法。
- 依赖倒转原则:高层模块不应该依赖底层模块,两者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象。
- 接口隔离原则:一个类对另一个类的依赖应该建立在最小的接口上。
- 迪米特法则:如果两个软件实力无须直接通信,那么就不应该当发生直接的相互调用,可以通过第三方转发调用,目的在于降低类之间的耦合度,提高模块的相对独立性。
- 合成复用原则:尽量先使用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现。
设计模式定义
- 创建者模式::对象的创建与使用分离
- 单例模式:该模式涉及到一个单一的类;该类负责创建自己的对象,同时确保只有单个对象被创建,这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。(饿汉单例模式和懒汉单例模式)
- 原型模式:用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型对象相同的对象。
- 工厂模式:定义一个用于创建对象的接口,让子类决定实例化哪个产品类对象,工厂方法使一个产品类的实例化延迟到其工厂的子类。
- 抽象工厂模式:是一种为访问类提供一个创建一组相关的或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到不同族的不同等级的产品的横式结构。
- 建造者模式:将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的表示。分离了部件的构建和装配。从而可以构建出复杂的对象。这个模式适用于某个对象的构建过程复杂的情况。
- 结构型模式: 结构型行为模式描述如何将类或者对象按某种布局组成更大的结构,它分为类结构模式和对象结构模式,前者采用继承机制来组织接口和类,后者采用组合或聚合来组合对象。
- 代理模式:由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。Java中的代理按照代理类生成时机不同又分为静态代理和动态代理。静态代理代理类在编译期就生成,而动态代理则是在Java运行时动态生成,动态代理又有JDK和CGLib两种方式。
- 适配器模式:将一个类的接口转换成客户希望的另一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作。适配器模式分为类适配器和对象适配器模式,前者类之间的耦合度比后者高,且要求程序员了解现有组件库中的相关组件的内部结构,所以应用相对少一些而对象适配器用的多一些。
- 桥接模式:将抽象与实现分离,使它们可以独立变化,它是组合关系代替继承关系实现,从而降低了抽象和实现这两个可变维度的耦合度。
- 装饰者模式:指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式
- 外观模式:是一种通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式,该模式对外有一个统一的接口,外部应用程序不用关心内部子系统的具体的细节,这样会大大降低应用程序的复杂度,提高了程序的可维护性。
- 享元模式:运用共享技术来有效地支持大量细粒度对象的复用,它通过共享已经存在的对象来大幅度地减少需要创建的对象数量,避免大量相似对象的开销,从而提高系统资源的利用率。
- 组合模式:又名部分整体模式,是用于把一组相似的对象当做一个单一的对象,组合模式依据树形结构来组合对象,用来表示部分以及整体层次,这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。
- 行为型模式: 行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样互相协作共同完成单个对象都无法单独完成的任务,它涉及算法和对象间职责的分配。 行为型模式分为类行为型模式和对象行为型模式,前者采用继承机制来在类间分派行为,后者采用组合或者聚合在对象间分配行为,由于组合关系或者聚合关系比继承关系耦合度低,满足“合成复用性原则”,所以对象行为模式比类行为模式具有更好的灵活性。
- 模板方法模式:定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。
- 策略模式:该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响到使用的用户。它通过对算法进行封装,把使用的算法的责任和算法的实现分离开来,并委派给不同的对象对这些算法进行管理。
- 命令模式:将一个请求封装成为一个对象,使发出请求的责任和执行请求的责任分隔开,这样两者之间通过命令进行沟通,这样方便将命令对象进行存储、传递、调动、增加和管理。
- 职责链模式:又名职责链模式,为了避免请求发送者与多个请求处理者耦合在一起,将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链,当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止。
- 状态模式:对有状态的对象,把复杂的“判断逻辑”提取到不同的状态对象中,允许状态对象在其内部状态发生改变时改变其行为。
- 观察者模式:又称发布-订阅模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听一个主题对象,这个主题对象在状态变化时,会通知所有的观察者对象,使他们都能够自动更新自己。
- 中介者模式:又称为调停模式,定义一个中介角色来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立变换他们之间的交互。
- 迭代器模式:提供一个对象来顺序访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示。
- 访问者模式:封装一些作用于某种数据结构中的各元素的操作,它可以在不改变这个数据结构的前提下定义作用这些元素的新的操作。
- 备忘录模式:又叫快照模式,在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以使以后当需要时能将该对象恢复到原先保存的状态。
- 解释器模式:给定一个语言定义它的语法表示,并定义一个解释器,这个解释器使用标识符来解释语言中的句子。
设计模式使用场景
- 创建型模式:
- 单例模式:
- 原型模式:
- 对象的创建非常复杂,可以使用原型模式快捷地创建对象
- 性能和安全的要求比较高
- 工厂模式:
- 抽象工厂模式:
- 当需要创建的对象是一系列相互关联或相互依赖的的产品族时
- 系统中有多个产品族,但每次只使用其中的某一族产品
- 系统中定义了产品的类库,且所有的产品接口相同,客户端不依赖产品实例的创建细节和内部结构。
- 建造者模式:
- 创建的对象较复杂,由多个部件组成,各部件面临着复杂的变化,但构件间的建造顺序是稳定的
- 创建复杂对象的算法独立于该对象的组成部分以及它们的装配方式,即产品的构建过程和最终的表示是独立的
- 结构型模式:
- 代理模式:
- 远程代理
- 防火墙代理
- 保护代理
- 适配器模式:
- 以前开发的系统存在满足新系统功能需求的类,但其接口和新系统的接口不一致
- 使用第三方提供的组件,但组件接口定义和自己要求的接口定义不一致
- 桥接模式:
- 当一个类存在两个独立变化的维度,且两个维度都需要进行扩展时
- 当一个系统不希望使用继承或因为多层次继承导致系统类的个数急剧增加时
- 当一个系统需要在构件的抽象化角色之间增加更多的灵活性时,避免在两个层次之间建立静态的继承关系,通过桥接模式可以使它们在抽象建立一个关联关系
- 装饰者模式:
- 当不能采用继承的方式对系统进行扩充或者采用继承不利于系统扩展和维护时
- 在不影响其他对象的情况之下,以动态、透明的方式给单个对象添加职责
- 当对象的功能要求可以动态地添加,也可以再动态地撤销时
- 外观模式:
- 对分层结构系统构建时,使用外观模式定义子系统中每层的入口点可以简化子系统之间的依赖关系
- 当一个复杂的系统子系统很多时,外观模式可以为系统设计一个简单的接口供外界进行访问
- 当客户端与多个子系统之间存在很大的联系时,引入外观模式可以将它们分离,从而提高子系统的独立性和可移植性
- 享元模式:
- 一个系统有大量相同或者相似的对象,造成内存的大量浪费
- 对象的大部分状态都是可以外部化,可以将这些外部状态传入对象中
- 在使用享元模式时需要维护一个存储享元对象的享元池,而这需要耗费一定的系统资源,因此,应当在需要多次重复使用享元对象时才值得使用享元模式
- 组合模式:
- 组合模式正式应树形结构而生,所以组合模式的使用场景就是出现树形结构的地方。如:文件目录结构、多级目录呈树形结构数据的操作
- 代理模式:
- 行为性模式:
- 模板方法模式:
- 算法的整体步骤都很固定,但其中个别部分易变时,这时候可以使用模板方法模式,将容易变的部分抽象出来,供子类实现
- 需要通过子类来决定父类算法中某个步骤是否执行,实现子类对父类的反向控制
- 策略模式:
- 一个系统需要动态地在几种算法中选择一种时,可将每个算法封装到策略类中
- 一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现,可将每个条件分支移入它们各自的策略类中以代替这些条件语句
- 系统中各算法彼此完全独立,且要求对客户隐藏具体算法的实现细节
- 系统要求使用算法的客户不应该知道其操作的数据时,可使用策略模式来隐藏与算法相关的数据结构
- 多个类只区别在表现行为不同,可以使用策略模式,在运行时动态选择具体要执行的行为
- 命令模式:
- 系统需要将请求调用者和请求接收者解耦,使得调用者和接收者不直接交互
- 系统需要在不同的时间指定请求,将请求排队和执行请求
- 系统需要支持命令的撤销操作和恢复操作
- 职责链模式:
- 状态模式:
- 当一个对象的行为取决于它的状态,并且它必须在运行时根据状态去改变它的行为时
- 一个操作中含有庞大的分支结构,并且这些分支决定于对象的状态时
- 观察者模式:
- 对象间存在一对多的关系,一个对象的状态发生改变会影响其他对象
- 当一个抽象模型有两个方面,其中一个方面依赖于另一个方面时
- 中介者模式:
- 系统中对象之间存在复杂的引用关系,系统结构混乱且难以理解
- 当想创建一个运行多个类之间的对象,又不想生成新的子类时
- 迭代器模式:
- 当需要为聚合对象提供多种遍历方式时
- 当需要为遍历不同的聚合结构提供一个统一的结口时
- 当访问一个聚合对象的内容而无须暴露其内部细节的表示时
- 访问者模式:
- 对象结构相对稳定,但其操作算法经常变化的程序
- 对象结构中的对象需要提供多种不同且不相关的操作,而且要避免让这些操作的变化影响对象的结构
- 备忘录模式:
- 需要保存与恢复数据的场景,如玩游戏时的中间结果的存档功能
- 需要提供一个可以回滚操作的场景,如Word、记事本、Photoshop、Idea等软件在编辑时按Ctrl + Z组合键,还有数据库中的事务操作
- 解释器模式:
- 当语言中的文法较为简单,且执行效率不是关键性的问题时
- 当问题重复出现,且可以用一种简单的语言来进行表达时
- 当一个语言需要解释执行,并且语言中的句子可以表示为一个抽象语法树的时候
- 模板方法模式: