23种设计模式意图及场景

编号

模式名

意图场景速记
1工厂方法定义一个创建对象的(工厂)接口,让其子类决定实例化哪一个(产品)类。该模式使一个(产品)类的实例化延迟到其(工厂)子类进行
  • 当一个类不知道它所必须创建的对象的类
  • 当一个类希望由它的子类来指定它所创建的对象
  • 当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化
动态生产对象
2抽象工厂提供一个接口,可以创建一系列相关或相互依赖的对象,而无需指定它们具体的类
  • 一个系统要独立于它的产品的创建、组合和表示时
  • 一个系统要由多个产品系列中的一个来配置时
  • 当要强调一系列相关的产品的设计以便进行联合使用时
  • 当提供一个产品类库,只想显示它们的接口而不是实现时
生产系列对象
3构建器将一个复杂类的表示和其构造相分离,使得相同的构建过程能够得出不同的表示
  • 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时
  • 当构造过程必须允许被构造的对象有不同的表示时
复杂对象构造
4原型用原型实例指定创建对象的类型,并且通过拷贝这个原型来创建新的对象
  • 当一个系统应该独立于它的产品的创建、构成和表示时
  • 当要实例化的类是在运行时刻指定时,例如通过动态装载
  • 为了避免创建一个与产品类层次平行的工厂类层次时
  • 当一个类的实例只能有几个状态组合中的一种时。建立相应数目的原型并克隆它们,可能比每次用合适的状态手工实例化该类更方便些
克隆对象
5单例保证一个类只有一个实例,并提供一个访问它的全局访问点
  • 当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时
  • 当这个唯一实例应该是通过子类化可扩展的,并且客户无需更改代码就能使用一个扩展实例时
单实例
6适配器将一个类的接口转换成用户希望得到的另一种接口,它使原本不相容的接口得以协同工作
  • 想使用一个已经存在的类,而它的接口不符合要求
  • 默认空实现一个复杂接口的所有方法,方便客户继承并覆写感兴趣的
接口转换
7桥接将类的抽象部分和它的实现部分分离开,使它们可以独立变化
  •  不希望在抽象和实现部分之间有一个固定的绑定关系。例如这种情况可能是因为,在程序运行时刻实现部分应可以被选择或切换
  • 类的抽象以及它的实现都应该可以通过生成子类的方法加以扩充。这是Bridge模式使得开发者可以对不同的抽象接口和实现部分进行组合,并分别对它们进行扩充
  • 对一个抽象的实现部分的修改应对客户不产生影响,即客户代码不需要重新编译。
  • (C++)想对客户完全隐藏抽象的实现部分
  • 有许多类要生成的类层次结构
  • 想在多个对象间共享实现(可能使用引用计数),但同时要求客户并不知道这一点
多维度,继承树拆分
8组合将对象组合成树型结构以表示“整体-部分”的层次结构,使得用户对单个对象和组合对象的使用具有一致性
  • 想表示对象的部分-整体层次结构
  • 希望用户忽略组合对象与单个对象的不同
树型目录结构
9装饰动态地给一个对象添加一些额外的职责。它提供了用子类扩展功能的一个灵活的替代,比派生一个子类更加灵活
  • 不影响其它对象的情况下,以动态、透明的方式给单个对象添加职责
  • 处理那些可以撤销的职责
  • 不能采用生成子类的方式进行扩充时
附加职责
10外观定义一个高层接口,为子系统中的一组接口提供一个一致的外观,从而简化了该子系统的使用
  • 对分层结构系统构建时,使用外观模式定义子系统中每层的入口点可以简化子系统之间的依赖关系。
  • 当一个复杂系统的子系统很多时,外观模式可以为系统设计一个简单的接口供外界访问。
  • 当客户端与多个子系统之间存在很大的联系时,引入外观模式可将它们分离,从而提高子系统的独立性和可移植性。
对外统一接口
11享元提供支持大量细粒度对象共享的有效方法
  • 系统中存在大量相同或相似的对象,这些对象耗费大量的内存资源。
  • 大部分的对象可以按照内部状态进行分组,且可将不同部分外部化,这样每一个组只需保存一个内部状态。
  • 由于享元模式需要额外维护一个保存享元的数据结构,所以应当在有足够多的享元实例时才值得使用享元模式。
对象共享
12代理为其他对象提供一种代理以控制这个对象的访问
  • 远程代理,这种方式通常是为了隐藏目标对象存在于不同地址空间的事实,方便客户端访问。例如,用户申请某些网盘空间时,会在用户的文件系统中建立一个虚拟的硬盘,用户访问虚拟硬盘时实际访问的是网盘空间。
  • 虚拟代理,这种方式通常用于要创建的目标对象开销很大时。例如,下载一幅很大的图像需要很长时间,因某种计算比较复杂而短时间无法完成,这时可以先用小比例的虚拟代理替换真实的对象,消除用户对服务器慢的感觉。
  • 安全代理,这种方式通常用于控制不同种类客户对真实对象的访问权限。
  • 智能指引,主要用于调用目标对象时,代理附加一些额外的处理功能。例如,增加计算真实对象的引用次数的功能,这样当该对象没有被引用时,就可以自动释放它。
  • 延迟加载,指为了提高系统的性能,延迟对目标的加载。例如,Hibernate 中就存在属性的延迟加载和关联表的延时加载。
快捷方式
13职责链通过给多个对象处理请求的机会,减少请求的发送者与接收之间的耦合。将接收对象链接起来,在链中传递请求,直到有一个对象处理这个请求
  • 多个对象可以处理一个请求,但具体由哪个对象处理该请求在运行时自动确定。
  • 可动态指定一组对象处理请求,或添加新的处理者。
  • 需要在不明确指定请求处理者的情况下,向多个处理者中的一个提交请求。
传递职责
14命令将一个请求封装为一个对象,从而可用不同的请求对客户进行参数化,将请求排队或记录请求日志,支持可撤销的操作
  • 请求调用者需要与请求接收者解耦时,命令模式可以使调用者和接收者不直接交互。
  • 系统随机请求命令或经常增加、删除命令时,命令模式可以方便地实现这些功能。
  • 当系统需要执行一组操作时,命令模式可以定义宏命令来实现该功能。
  • 当系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作时,可以将命令对象存储起来,采用备忘录模式来实现。
请求变对象,日志记录,可撤销
15解释器给定一种语言,定义它的文法表示,并定义一个解释器,该解释器用来根据文法表示来解释语言中的句子
  • 当语言的文法较为简单,且执行效率不是关键问题时。
  • 当问题重复出现,且可以用一种简单的语言来进行表达时。
  • 当一个语言需要解释执行,并且语言中的句子可以表示为一个抽象语法树的时候,如 XML 文档解释。
虚拟机解释执行
16迭代器提个一种方法来顺序访问一个聚合对象中的各个元素,从而不需要暴露该对象的内部表示
  • 当需要为聚合对象提供多种遍历方式时。
  • 当需要为遍历不同的聚合结构提供一个统一的接口时。
  • 当访问一个聚合对象的内容而无须暴露其内部细节的表示时。
统一的遍历
17中介者用一个中介对象来封装一系列的对象交互。它使各对象不需要显式地相互调用,从而达到低耦合,还可以独立地改变对象间的交互
  • 当对象之间存在复杂的网状结构关系而导致依赖关系混乱且难以复用时。
  • 当想创建一个运行于多个类之间的对象,又不想生成新的子类时。
不直接引用
18备忘录在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,从而可以在以后将该对象恢复到原先保存的状态
  • 需要保存与恢复数据的场景,如玩游戏时的中间结果的存档功能。
  • 需要提供一个可回滚操作的场景,如 Word、记事本、Photoshop,Eclipse 等软件在编辑时按 Ctrl+Z 组合键,还有数据库中事务操作。
保存内部状态,可恢复
19观察者定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新
  • 对象间存在一对多关系,一个对象的状态发生改变会影响其他对象。
  • 当一个抽象模型有两个方面,其中一个方面依赖于另一方面时,可将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。
  • 实现类似广播机制的功能,不需要知道具体收听者,只需分发广播,系统中感兴趣的对象会自动接收该广播。
  • 多层级嵌套使用,形成一种链式触发机制,使得事件具备跨域(跨越两种观察者类型)通知。
通知更新
20状态允许一个对象在其内部状态改变时改变它的行为
  • 当一个对象的行为取决于它的状态,并且它必须在运行时根据状态改变它的行为时,就可以考虑使用状态模式。
  • 一个操作中含有庞大的分支结构,并且这些分支决定于对象的状态时。
状态变成类
21策略定义一系列算法,把它们一个个封装起来,并且使它们之间可互相替换,从而让算法可以独立于使用它的用户而变化
  • 一个系统需要动态地在几种算法中选择一种时,可将每个算法封装到策略类中。
  • 一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现,可将每个条件分支移入它们各自的策略类中以代替这些条件语句。
  • 系统中各算法彼此完全独立,且要求对客户隐藏具体算法的实现细节时。
  • 系统要求使用算法的客户不应该知道其操作的数据时,可使用策略模式来隐藏与算法相关的数据结构。
  • 多个类只区别在表现行为不同,可以使用策略模式,在运行时动态选择具体要执行的行为。
多方案切换
22模板方法定义一个操作中的算法骨架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构即可重新定义算法的某些特定步骤
  • 算法的整体步骤很固定,但其中个别部分易变时,这时候可以使用模板方法模式,将容易变的部分抽象出来,供子类实现。
  • 当多个子类存在公共的行为时,可以将其提取出来并集中到一个公共父类中以避免代码重复。首先,要识别现有代码中的不同之处,并且将不同之处分离为新的操作。最后,用一个调用这些新的操作的模板方法来替换这些不同的代码。
  • 当需要控制子类的扩展时,模板方法只在特定点调用钩子操作,这样就只允许在这些点进行扩展。
文档模板填空
23访问者表示一个作用于某对象结构中各元素的操作,使得在不改变各元素的前提下定义作用于这些元素的新操作
  • 对象结构相对稳定,但其操作算法经常变化的程序。
  • 对象结构中的对象需要提供多种不同且不相关的操作,而且要避免让这些操作的变化影响对象的结构。
  • 对象结构包含很多类型的对象,希望对这些对象实施一些依赖于其具体类型的操作。
数据与操作分离

(1-5:创建型;6-12:结构型;13-23:行为型)(下划线即是类模式又是对象模式)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值