快速定位23种设计模式

288 阅读34分钟

此文章意在写代码的决策阶段快速定位自己想要的设计模式,或者理顺设计模式的知识点时使用的。每个设计模式的具体内容请自行查找相关文章。

此文章为工具型文章,并非知识分享型文章。由于文字量较大,所以难免出现错别字,请大家帮忙支出,谢谢

一. 创建型模式

对象模板(object template pattern)

是什么:

对象模板模式使用类或者结构体作为数据类型机器逻辑的规范。创建对象时使用模板,并在初始化时完成数据赋值。赋值时,要么使用模板中的默认值,要么是用类或者结构体的初始化器来提供数值。

优点:

对象模板模式为将数据与操作数据的逻辑组织在一起,即封装,提供了基础。封装时的对象可以在为其用户提供接口(API)的同时,隐藏接口的内部实现。这有利于防止组件之间行程紧耦合。

何时使用:

除非是机器简单的项目,否则你都应该使用此模式。景观元祖是Swift的特性,但是从长远来看,使用他表示数据会引发一些维护问题,而创建一个类或者结构体并不是很复杂。

何时避免使用:

这个模式本身并没有问题。但是在数据通信时应该考虑采用dic。

如何确定是否正确实现了此模式:

如果修改类或者结构体的内部是现实,使用了此模式的组件无需做出相应的改变,则说明你正确的实现了此模式。

有哪些常见陷阱:

唯一的陷阱是,应该使用类作为模板的时候却使用了结构体。结构体和类具有很多共同之处,但是当他们创建的对象赋值给新变量时他们的行为并不一致。

有哪些相关的模式:

原型

原型(prototype pattern)

是什么:

原型模式通过克隆已有的对象来创建新的对象,已有的对象即为原型

优点:

使用这个模式的主要益处是,将创建对象的代码隐藏,即代码对于使用它的组件是不可见的。这就意味着,组件无需知道创新的对象需要用哪些类或者结构,也不需要了解初始化器的细节,即使创建子类并实例化,相关组件也不用修改。每次初始化一个新的对象,都需要消费一定的时间,使用这个模式能避免重复耗时的过程。

何时使用:

当你在编写组件且需要创建新的实例,但又不想依赖类的初始化器时,可以使用此模式。

何时避免使用:

此模式没有什么弊端,不过应该在了解其他模式的基础上,才能确保此模式是最佳选择。

如何确定是否正确实现了此模式:

为了测试是否正确的实现了此模式,你可以修改创建原型对象的类或者结构体的初始化器,并检查是否需要在创建克隆对象的组件中做出相应的改变。为了二次确认实现的正确性,你可以创建一个原型类的子类,并且确保相关组件可以再不做任何改变的情况下克隆该子类。

有哪些常见陷阱:

最主要的一个陷阱是,在克隆原型对象的时候,你可能会选错复制的类型。复制可分为深复制和浅复制,选择正确的复制类型对应用而言至关中重要。

有哪些相关的模式:

  • 对象模板

  • 单例,单例模式提供类一种方法,是的同一个对象可以在多处共享,避免重复创建多个实例。

选择浅复制还是深复制

应该选择浅复制还是深复制,并么有固定的规则,具体应该喧杂额那一种方式,还得根据类的情况来决定。做决定是,应该考虑三个因素,分别是复制对象的工作量,存储副本所需的内存和副本对象的使用方式。

最后一个因素,也就是副本对象的使用方式,才是最重要的。多个独享共享内存是否有意义,修改某一个属性的操作,是否适用于其他共享对象?

个人给出的最好建议是,做决定是思考一下创建对象的目的是什么,并找出刻在所有给予原型创建的副本中通用的对象。如果不确定,先从潜伏之开始,因为它实现起来最简单。尽管有时这么做并不合适,但是这样不用到处实现NSCopying协议,就可以测试代码的效果。

单例(singletion pattern)

单例可以确保某个类型的对象在应用中只有一个实例。这是最常用的设计模式之一,因为它所解决的问题很常见。例如,当你需要使用单个对象来表示现实世界中的资源,或者想要一种统一的方式来处理所有同类型的任务(比如输出日志)时,都可以使用此模式。

是什么:

单例模式能够确保某种类型的对象在应用中只存在一个实例。

优点:

单例模式可以用于管理代表现实世界资源的对象,或封装共享资源。

何时使用:

党进一步创建对象并不能增加现实中的可用资源,或者希望一项行为,比容日志输出,始终一致时,就可以使用单例模式。

何时避免使用:

如果不存在多个组件访问共享资源的情况,或者应用没有代表现实资源的对象,单例模式就没有太大作用。

如何确定是否正确实现了此模式:

当一个给定类只存在一个实例,并且该实例无法被赋值或者克隆,也不能创建更多的实例时,就说明正确实现了单例模式。

有哪些常见陷阱:

最常见的陷阱是,使用引用类型(可以被复制)或者使用实现了NSCopying协议的类(可以被克隆)。单例模式通常需要正对并发放稳实现一些保护机制,毕竟并发放稳会引起许多问题。

有哪些相关的模式:

对象池模式。对象池模式适合用来管理固定数量的多个对象,而单例模式责之管理一个对象。

对象池(object pool pattern)

对象池模式是单例的一种变体,他可以为组件提供多个完全相同的对象,而非单个对象。当你需要管理一组表示客户想替代的资源的对象,且要求同一时刻只允许一个组件使用同一个对象时,便可使用对象池模式。

是什么:

对象池模式一般用来管理一组可充用的对象,一共调用组件使用。组件可以从对象池中获取对象。用它来完成任务,用完后将对象还给对象池,以满足足见未来的使用需求,一个对象在被分配给某个调用组件后,其他组件在他返回对象池以前都无法使用它。

优点:

对象池模式兼顾地向的构建过程隐藏,使组件无需了解此过程。同事,对象池模式通过重用机制将对象初始化的高昂成本摊销。

何时使用:

不管是因为需要使用对象来表示现实世界中的资源,还是因为对象的初始化成本高昂,而需要创建一组完全相同的对象,我们都可以使用对象池模式

何时避免使用:

若需要保证任意时刻只存在一个对象,则不应该使用此模式,而应该使用单例模式。如果对存在的对象的数量没有限制,并允许调用组件自行创建实例,也不应该使用此模式,应该使用其他模式,比如工厂。

如何确定是否正确实现了此模式:

若能在创建新势力的情况下给调用组件分配对象,并且相关对象返回到对象池后可以满足组建的后续请求,就说明正确地实现了对象池模式。

有哪些常见陷阱:

最重要的陷阱是并发保护的实施,只有正确地实现了兵法保护,才能保证对象的正确分配,确保永不实现此模式的数据结构不会受到损坏。

有哪些相关的模式:

单例模式与对象模式有不少相似之处,但是前者只管理单个对象。

工厂方法(factory method pattern)

当你需要在让类实现同一个协议还是让泪继承同一个基类之间做选择时,便可以使用工厂方法模式。此模式是的调用组件无需了解为其提供具体服务的实现类的细节,以及这些类之间的关系,即可获得所需的服务。

是什么:

工厂方法模式通过选区相关的实现类来满足调用组件的请求,调用组件无需了解这些实现类的细节以及他们之间的关系。

优点:

工厂方法模式统一了实现类的选取逻辑,避免了相关的逻辑散布于整个程序的情况。也就是说,调用组件只依赖顶层协议或者积累,无需了解实现类机器选取的过程。

何时使用:

当存在多个类共同实现一个协议或者共同继承一个积累是,就可以使用工厂方法模式。

何时避免使用:

不存在共同协议或者没有共同基类时,则不应该使用此模式,因为此模式的运作机制要求调用组件只能依靠单一类型。

如何确定是否正确实现了此模式:

如果调用组件不知道使用了那个累,也不知道该类的选取方式,就正确的第十礼花了合适的类,就说明正确地实现了此模式。

有哪些常见陷阱:

无。

有哪些相关的模式:

工厂方法通常会于单例模式和对象池模式一起使用。

抽象工厂(abstract factory pattern)

该模式与工厂模式类似。不同的是,抽象工厂允许调用组件在不了解创建对象所需的情况下,创建一组或一系列相关的对象。

是什么:

抽象工厂模式允许调用组件创建一组相关联的对象。调用组件无需了解创建对象所使用的类,以及选择这些类的理由。这个模式与工厂方法模式类似,不同的是,此模式可以为调用组件提供一组对象。

优点:

抽象工厂模式允许调用组件不必了解创建对象时用的类,也不知道选择这些累的原因。因此,我们可以在不修改调用组件的情况下,对其使用的类进行修改。

何时使用:

如果调用组件需要使用多个相互协作的对象,同事无需了解这些对象之间的写作方式是,就可以使用此模式。

何时避免使用:

如果只是创建一个对象,就不要使用此模式。这种场景下,应该使用相对简单的工厂方法模式。

如何确定是否正确实现了此模式:

如果调用组件可以在不了解创建对象所使用的类,正确地接受到一组对象,就说明实现是正确的。正常情况下,调用组件只有通过对象所实现的协议或者继承的积累才能使用这些对象的功能。

有哪些常见陷阱:

主要的陷阱是,将调用组件所使用的类的细节暴露给调用组件。比如,调用组件对选择实现类的决策过程存在一类,或者对具体的莫各类存在依赖。

有哪些相关的模式:

如果只是创建一个对象,应该使用相对简单的工厂方法模式。抽象工厂方法模式通常配合单例模式和原型模式一起使用。

建造者(builder pattern)

建造者模式为了分离对象的创建与配置。调用组件负责提供配置对象的数据,并负责将配置数据传给中间人,即建造者,而建造者则代表调用组件创建对象。如此分离之后,调用组件就无需过多掌握其所使用的对象的信息,将默认配置信息及中方在建造这类中即可,而不用讲这些信息散布于每一个需要创建对象的调用组件中。

是什么:

使用建造者模式可以将创建对象所需的逻辑和默认配置放入一个建造者类中。这样调用组件只需要了解少量配置数据即可创建对象。并且无需了解创建对象所需的默认数据值。

优点:

使用此模式让修改创建对象所需的默认配置值变得更简单,同时也让更改创建实例所使用的类更为方便。

何时使用:

如果创建对象所需进行复杂的配置,而你又不想让默认配置值在整个应用中传播,即可使用此模式。

何时避免使用:

当每次创建对象所需的各个数据值都不相同时,不要使用此模式。

如何确定是否正确实现了此模式:

如果在调用组件创建对象时,秩序为其提供默认值中没有的数据(不过,也可以提供一些值以重写部分或者全部默认值),那么就说明你正确地实现了此模式。

有哪些常见陷阱:

无。

有哪些相关的模式:

此模式可以与工厂方法模式或者抽象工厂模式结合使用,并更具调用组件提供的配置信息更变用于创建对象的实现类。

二. 结构型模式

适配器(adapter pattern)

使用此模式可以让来年各个提供相关功能的对象协作,甚至在他们的API不兼容的情况下进行配合。

是什么:

适配器模式通过引入适配器对两个组件进行适配的方式,可以让两个API不兼容的组件协作。

优点:

此模式可以帮助你将无法修改源代码的组件集成到你的应用中。在使用第三方框架或利用另一个项目输出的数据是,通常会遇到组件之间的兼容问题,二此模式可以帮助你解决这类问题。

何时使用:

当需要将一个与其他组件相似的功能组件集成到现有的项目中,而该组件所使用的API🈶于你的项目不兼容,便可使用此模式。

何时避免使用:

如果可以修改所要继承的组件的源码,或者可以直接将该组件提供的数据迁移到应用中是,则不应该使用此模式。

如何确定是否正确实现了此模式:

如果无需修改引用功能或者相关组件,只需要使用适配器即可将相关组件集成到现有项目中,那么就说明你正确的实现了此模式。

有哪些常见陷阱:

此模式的唯一陷阱是,在实现过程中时视图拓展此模式,以强行让带适配的API提供该组件原来并未提供的功能。

有哪些相关的模式:

许多结构模式都有类似的实现,只是目的不一样。

桥接(bridge pattern)

桥接模式不太好理解,尽管她看起来与适配器模式有点类似,但是它的用法并不太直观。

是什么:

桥接模式通过分离应用的抽象部分与实现部分,是的他们可以独立第变化。桥接模式常被用来解决所谓的类层级爆炸的问题。味精深思熟虑地反复进行重构,一般会导致类层级爆炸的问题出现。此外通过不断创建新的类的方式来给应用增加新的工鞥,也会引起这种问题。

优点:

用桥接模式解决类层级爆炸问题的好处在于,为应用增加一个新功能时只需要新建一个类。更广泛地将,此模式分离了应用的抽象部分与实现部分的变化。

何时使用:

可以使用此模式解决类层级爆炸的问题,或者对不同AP进行桥接。

何时避免使用:

在继承三方组件不应该使用此模式,而应该使用适配器模式。

如何确定是否正确实现了此模式:

酒类层级爆炸问题而言,如果新增功能或者增加对新平台的支持,只用创建一个累的话,说明正确地是下了此模式。更广泛地将,如果不需要对相应的实现部分作修改就可以改变抽象部分(比如协议或者闭包的签名),就说明正确地实现了此模式。

有哪些常见陷阱:

如果没有讲评待相关的代码与通用代码进行分离,是无法解决类层级爆炸问题的

有哪些相关的模式:

许多结构模式的实现都差不多,但是他们的意图是不同的。

装饰器

修饰器模式可以用于在运行时选择性地修改对象的行为。此模式的使用场景很多,在处理无法修改的类时能发挥强大的功能。选择性地修改的意思是,你可以选择修改哪些对象,以及保持哪些对象的原有功能。

是什么:

使用装饰器模式,我们可以在不修改杜向所属的类或者对象的使用者的情况下,修改单个对象的行为。

优点:

装饰器模式中定义的行为,即改变后的对象行为,能够在不创建大量的子类的情况下,组合起来实现复杂的效果。

何时使用:

如果想修改某些对象的行为,但又不想改变该对象所属的类或者使用者,就可以使用此模式。

何时避免使用:

如果可以修改你想修改的类的实现,那就不要使用此模式。此时直接修改类往往更加简单。

如何确定是否正确实现了此模式:

如果可以在不修改类的实现的情况下,选择性的修改某个类的不分对象(并且这种修改不会影响其他对象),则说明你正确地实现了此模式。

有哪些常见陷阱:

此模式最主要的一个陷阱是,错误地实现此模式之后,他所桌的修改会对所有对象产生影响,既无法选择性地修改某些对象。还有一个比较少见的陷阱,即实现此模式之后会产生一些与对象原意图无关的副作用。

有哪些相关的模式:

许多结构模式的实现基本都差不多,但是他们的意图并不相同。

组合

组合模式的应用范围并没有介绍的其他设计模式那么广,但是由于它能够让包含多种不同类型的对象的数据结构具有一致性,因此他也是一种重要的设计模式。

是什么:

聚合模式能够将对象以树形结构组织起来,使得外界对单个对象和组合对象使用具有一致性。

优点:

组合模式所带的一致性是指,调用组件使用这些以树形结构组织其起来对象时更加简单,无需了解其中各个不同类型的对象的细节信息。

何时使用:

当操作的数据具有一个含有叶子节点(leaf node)和一组对象的树形结构时,就可以使用这个模式。

何时避免使用:

此模式只适用于树这种数据结构。

如何确定是否正确实现了此模式:

当时用这种属性结构的调用组件能够通过同一个类或者协议来使用树中包含的所有的对象时,就说明你正确地实现了此模式。

有哪些常见陷阱:

此模式最合适应用于创建之后就不再需要修改的树形结构。如果通过此模式增加修改树形结构的功能,那此模式的有点就不复存在了。

有哪些相关的模式:

许多结构型模式都有类似的实现,只是目的不同。在选用此部分介绍的设计模式时,要确保选择的模式是你想要的。

外观

外观模式一般用于建华一个或者多个类提供的API,以让常见任务可以更简便地执行。同时,也可以让与API相关的复杂代码集中于一处。

是什么:

外观模式可简化复杂的常见任务API的使用

优点:

使用此模式,可以将于API使用相关的复杂代码集中于一处,这不仅可以将API变化带来的影响最小化,还能够简化使用API的调用组件的代码。

何时使用:

如果多个类需要协作,但彼此之间五象湖兼容的API可用湿,便可使用外观模式。

何时避免使用:

如果你的目标是将一个组件集成到应用中,那就不应该使用外观模式。更好的选择是适配器模式。

如何确定是否正确实现了此模式:

如果使用此模式,调用组件执行常见任务是对底层对象和相关数据不存在依赖,则说明你正确地实现了此模式。

有哪些常见陷阱:

实现外观模式时创建的一个陷阱是,对外泄露了底层对象的细节。也就是说,调用组件依然对底层的类活相关数据类型存在依赖,后两者出现变化是,前者也要做相应变更。

有哪些相关的模式:

许多结构模式都有类似的实现,只是目的不同。在选用此部分介绍的设计模式是,要确保选择的模式是你想要的。

享元

当一组相似的对象依赖相同的数据集合时,就可以使用享元模式。向元模式可以让这些对象共享同一个数据集合,而不是为每个对象创建一个数据集合,这就节省了内存开销。

是什么:

享元模式可以在多个调用组件之间共享数据对象

优点:

向元模式可以加少创建数据对象的内存开销和工作量。共享数据的调用组件数越多,使用此模式带来的好处越明显。

何时使用:

如果你可以辨别和分离多个调用组件之间使用的数据中相同的部分,就可以使用此模式。

何时避免使用:

如果没有可以共享的数据集合,或者可以共享的数据数目较小且容易创建,则不应该使用此模式。

如何确定是否正确实现了此模式:

如果所有的调用组件都依赖于同一组不可变的共享数据对象(一般称为外部数据),并且各个组件自身有一套表示自身状态的数据(一般称为内部数据),则说明你正确地实现了此模式。调用组件可以安全第并发修改自身内部的数据,但不能修改外部数据。

有哪些常见陷阱:

实现此模式创建的陷阱包括:不小心创建多个外部数据集合、未对内部数据做并发操作保护、允许修改外部数据的操作,以及过渡优化创建外部数据的操作。

有哪些相关的模式:

许多结构型模式都有了类似的实现,只是目的不同。在选用此部分介绍的设计模式时,要确保选择的模式是你想要的。

代理模式

当需要使用代理对象来代替对象或资源是,即可使用此模式。代理模式的使用方式主要有三种。请确保使用正确的形式。

是什么:

代理模式的核心是一个对象--代理对象,此对象可以用于代表其他资源,比如另一个对象或者一种远程服务调用组件在代理对象上进行操作,反过来作用域底层资源。

优点:

使用代理模式可以对代理对象所代表的资源进行深层次的管理,当想要拦截或者对某种操作进行调整时,此模式会非常实用。

何时使用:

代理模式的使用场景主要有三种:一是定义一个面向网页或者RESTful服务等远程资源的接口,二是管理开销比较大的操作执行过程,最后一个是为其他对象的属性和方法加上访问控制。

何时避免使用:

如果遇到的问题不属于上述三种情形之一,则不应该使用此模式。相反可以使用其他结构型模式。

如何确定是否正确实现了此模式:

当代理对象可用于操作其代表的资源时,你就正确地实现了此模式。

有哪些常见陷阱:

在实现代理模式时唯一遇到的陷阱是,在使用代理模式为对象提供访问控制时,允许外籍直接实例化其所代理的类。

有哪些相关的模式:

许多结构型模式的实现都差不多,但是他们的意图是不同的,请选择合适的模式。

三. 行为型模式

责任链

当多个对象可以响应一个请求,而又不想讲这些对象的细节暴露给调用组件是,便可以使用责任链模式。

是什么:

责任链模式负责组织管理一序列能够对调用组件的请求作出相应得的对象。这里所说的对象序列被称为责任链,责任链中的每个对象都可能被用于处理某个请求。请求在这个链上传递,直到链上的某个对象决定处理此请求,或者到达链的尾部。

优点:

发出请求的调用组件并不知道责任链上的那一个对象最终处理了他的请求,这使得系统可以在不影响代用组建的情况下动态地重新组织、拓展和简化责任链上的对象拍立顺序,已实现最优排列。

何时使用:

当多个对象可以响应一个请求,而最终只有一个对象会处理请求时,即可使用此模式。

何时避免使用:

当只有一个对象可以处理请求,或者调用组件需要自行选择处理对象时,不应使用此模式。

如何确定是否正确实现了此模式:

当多个可以响应请求的对象被排列成一列,并可轮秋响应请求时,就说明你正确地实现了此模式。责任链上的对象除了持有链上下一个对象的链接之外,并不需要知道链上其他对象的细节。

有哪些常见陷阱:

开发者在实现此模式是常犯的一个错误就是,将责任脸上对象的细节暴露给链上其他对象,或者调用组件。

有哪些相关的模式:

责任链与命令模式有一些共同之处

命令

命令模式提供了一种封装方法调用细节的机制,基于这种机制我们可以实现延迟方法调用或者替换调用该方法的组件。

是什么:

命令模式提供了一种封装方法调用细节的机制,基于着这种机制我们可以实现延迟方法调用或者替换调用该方法的组件。

优点:

命令模式使用的场景非常多,其中最常见的一个场景是实现撤销操作和创建宏。

何时使用:

如果你想让组件在不了解方法所使用的对象,其中调用了哪些方法,或者方法所需的参数的情况下调用该方法的话,便可使用此模式。

何时避免使用:

长长的方法调用不应该使用此模式

如何确定是否正确实现了此模式:

如果一个组件可以在不了解一个对象或者方法本身的情况下,使用命令调用该对象的方法,就说明你正确地实现了此模式。

有哪些常见陷阱:

在实现此模式时,最主要的一个陷阱是要求组件在滴啊用对象的方法时,了解该对象或者方法的实现细节。

有哪些相关的模式:

使用备忘录模式可以捕获一个对象的整体内部装填,并且可以根据不活的快照恢复到原来的状态。

中介者

使用终结者模式可以简化合理化对象之间的通信。此模式是知名度最小的模式,但是却解决了一个非常常见的问题,并且可以大幅简化应用设计的复杂度。

是什么:

中介者模式通过引入中介者对象的方式简化了同类对象之间的通信。

优点:

使用中介者模式之后,对象无需与其他对象保持联系,只需要与中介者对象交互。

何时使用:

当你在处理一组相互间需要自由通信的对象时,便可使用此模式

何时避免使用:

如果你需要让一个对象给一组互不相关的对象发送通知是,则不应该使用此模式。相反,应该使用观察者模式。

如何确定是否正确实现了此模式:

如果每个对象都对其他同类对象一无所知,只需要与中介者对象交互,就说明你正确地实现了此模式。

有哪些常见陷阱:

中介者不应允许同类对象直接访问彼此的数据,否则这些对象之间将产生依赖。

有哪些相关的模式:

终结者于观察者模式密切相关,且两者尝尝配合使用。

观察者

观察者模式定义了一种一对多的依赖关系,让一个或者多个观察者对象监听器所关心的主体对象。这个主体对象在自身状态发生变化时,会给所有观察者对象发送通知。使用观察者模式可以让大量多组对象在较少依赖的情况下实现合作,因此这个模式被广泛应用。只要你使用现代UI框架开发过一款应用,就很可能使用过此模式。

是什么:

使用观察者模式可以让一个对象在不对另一个对象产生依赖的情况下,注册并接受该对象发出的通知。

优点:

此模式允许发送通知的对象在不了解通知接受者如何处理通知的情况下,以一种统一的方式给接受者发送通知,这有效降低了应用的设计难度。

何时使用:

当一个对象需要在不依赖另一个对象的情况下,接受到另一个对象发生变化的通知时,即可使用此模式。

何时避免使用:

除非通知的发送者与接受者在功能上不存在相互依赖的关系,否则就不应该使用此模式。在两者没有依赖关系的情况下,即使移除通知的接受者,通知的发送者也能正常运作。

如何确定是否正确实现了此模式:

如果一个对象可以在不对发送通知的对象产生依赖的情况下,正常地接受通知就说明你正确地实现了观察者模式。

有哪些常见陷阱:

最大的陷阱就是在实现此模式时,让发送通知的对象与接收通知的对象产生依赖。

有哪些相关的模式:

备忘录

备忘录模式与命令模式紧密相关,但他们之间也有一个重要的区别,即前者的用处是捕捉一个对象的完整状态,以便在后期对其进行重置。

是什么:

备忘录模式可以捕捉一个对象的完整状态,并将其保存到一个备忘录对象中,以后可以根据备忘录重置对象的状态。

优点:

使用备忘录模式无需记录和使用单独的撤销命令即可彻底充值一个对象的状态。

何时使用:

当你需要在未来的某个时间单,讲一个对象的状态恢复到某个“完善”的状态是,即可使用此模式。

何时避免使用:

只有需要将一个对象恢复到较早的状态时,才应该使用此模式。如果只是想撤销最近执行的几个操作,可以使用命令模式。

如何确定是否正确实现了此模式:

如果一个对象可以以某个时刻为起点,将对象的状态恢复到脚早前的状态,就说明你正确地实现了此模式。

有哪些常见陷阱:

最常见的陷阱就是,没能完整地捕捉对象的状态,或者没能完整地恢复对象状态。

有哪些相关的模式:

备忘录模式与命令模式的思想是一样的。

策略

使用策略模式可以在不修改或者不继承一个类的情况下扩展其功能。如果你需要向第三方开发者提供开发框架,且框架中关键的及各类发生人一变化时(不管变化多小),都需要进行广泛、高成本的测试和验证流程的话,那么使用策略模式会让你受益无穷。

是什么:

策略模式通过让一组算法对象遵循一个定义明确的协议的方式,使得我们可以在不修改原有类的情况下扩展其功能。

优点:

策略模式允许第三方开发者在不修改原有类的情况下改变类的行为。某些类在修改之后,需要经历复杂而且蛮长的验证过程,此模式可以有效降低这种修改的成本。

何时使用:

当你需要在不修改原有类的情况下改变类的行为是,即可使用此模式。

何时避免使用:

没有理由不用此模式。

如何确定是否正确实现了此模式:

如果可以在不修改的情况下,通过定义和使用一个新策略的方式扩展一个类,就说明你正确地实现了此模式。

有哪些常见陷阱:

无。实现此模式非常简单。

有哪些相关的模式:

策略模式常与访问者模式配合使用。

访问者

使用访问者模式,可以在不修改类的源码和不创建新的子类的情况下扩展类的行为,这点与策略模式有点类似。与策略模式不同的是,访问者模式的适用对象是各种对象的合集。

是什么:

使用访问者模式,可以在不修改类的源码和不创建新的子类的情况下扩展类的行为。

优点:

当你想将一组类作为框架的一部分提供给第三方开发者,而又不想让第三方开发者修改器源码时,就可以使用此模式。对于修改核心类之后,需要执行复杂的测试流程的项目,此模式也是非常实用的。

何时使用:

当有多个类需要管理一组哥哥不相同的对象,而又想对这些对象执行一些操作时,就可以使用此模式。

何时避免使用:

当所有的对象都是同一个类型,或者可以方便的修改相关的类时,就没必要使用此模式。

如何确定是否正确实现了此模式:

当访问这类可以通过定义能够处理一个集合中的所有对象方法,来扩展相关集合中的对象所属的类的行为时,就说明你正确地实现了此模式。

有哪些常见陷阱:

在实现此模式时唯一的陷阱就是,试图不用双分派技术。

有哪些相关的模式:

策略模式负荷开闭原则,而访问者模式则提供了支持此原则的另一种方式。

模板

使用模板方法模式可以更具不同的需求改变算法汇总的某些步骤的实现,当你需要实现一些默认行为同时又想允许其他开发者对其进行修改时,即可使用此模式。此模式虽然简单容易立即和实现,但使用广泛,在大多数公共框架(包括苹果提供的)中都可以发现其身影。

是什么:

使用模板方法可以允许第三方开发者,以创建子类或者定义闭包的方式,替换一个算法的某些步骤的具体实现。

优点:

在开发允许其他开发者进行扩展和定制的框架式,此模式非常实用。

何时使用:

使用此模式可以选择性地允许外界在不修改原有类的情况下,修改人以算法中的某些步骤的具体实现。

何时避免使用:

如果可以修改整个算法就不必使用此模式,但可以选用其他模式。

如何确定是否正确实现了此模式:

如果外界可以在不修改原有类的情况下,选择性地修改人以算法中的某些步骤的具体实现,就说迷你正确地实现了此模式。

有哪些常见陷阱:

无。

有哪些相关的模式:

此模式的目标有部分与策略模式和访问者模式类似。