设计模式-各种模式应用场景

知识共享许可协议 版权声明:署名,允许他人基于本文进行创作,且必须基于与原先许可协议相同的许可协议分发本文 (Creative Commons

创建型模式

将对象的创建与使用分离。这样可以降低系统的耦合度,使用者不需要关注对象的创建细节,对象的创建由相关的工厂来完成。
-  单例(Singleton)模式:某个类只能生成一个实例,该类提供了一个全局访问点供外部获取该实例,其拓展是有限多例模式。

-  原型(Prototype)模式:将一个对象作为原型,通过对其进行复制而克隆出多个和原型类似的新实例。

-  工厂方法(FactoryMethod)模式:定义一个用于创建产品的接口,由子类决定生产什么产品。

-  抽象工厂(AbstractFactory)模式:提供一个创建产品族的接口,其每个子类可以生产一系列相关的产品。

-  建造者(Builder)模式:将一个复杂对象分解成多个相对简单的部分,然后根据不同需要分别创建它们,最后构建成该复杂对象。

以上 5 种创建型模式,除了工厂方法模式属于类创建型模式,其他的全部属于对象创建型模式,

1.单例(Singleton)模式

某个类只能生成一个实例,该类提供了一个全局访问点供外部获取该实例,其拓展是有限多例模式。
    1.某类只要求生成一个对象的时候,如一个班中的班长、每个人的身份证号等。
    2.当对象需要被共享的场合。由于单例模式只允许创建一个对象,共享该对象可以节省内存,并加快对象访问速度。如 Web 中的配置对象、数据库的连接池等。
    3.当某类需要频繁实例化,而创建的对象又频繁被销毁的时候,如多线程的线程池、网络连接池等。

2.原型(Prototype)模式

将一个对象作为原型,通过对其进行复制而克隆出多个和原型类似的新实例。
    1.如果一个系统想要独立于它想要使用的对象时,可以使用原型模式,让系统只面向接口编程,在系统需要新的对象的时候,可以通过克隆原型来得到.  
    2.如果需要实例化的类是在运行时刻动态指定时,可以使用原型模式,通过克隆原型来得到需要的实例.

3.工厂方法(FactoryMethod)模式

定义一个用于创建产品的接口,由子类决定生产什么产品。
    1.客户类不关心使用哪个具体类,只关心该接口所提供的功能.  
    2.创建过程比较复杂,例如需要初始化其他关联的资源类,读取配置文件等.  
    3.接口有很多具体实现或者抽象类有很多具体子类时,  
    4.不希望给客户程序暴露过多的此类的内部结构,隐藏这些细节可以降低耦合度.      
    5.优化性能,比如缓存大对象或者初始化比较耗时的对象.   

4.抽象工厂(AbstractFactory)模式

提供一个创建产品族的接口,其每个子类可以生产一系列相关的产品。
    1.如果希望一个系统独立于它的产品的创建,组合和表示的时候,换句话说,希望一个系统只是知道产品的接口,而不关心实现的时候.  
    2.如果一个系统要由多个产品系列中的一个来配置的时候.换句话说,就是可以,就是可以动态地切换产品族的时候.  
    3.如果强调一系列相关产品的接口,以便联合使用他们的时候  

5.建造者(Builder)模式

将一个复杂对象分解成多个相对简单的部分,然后根据不同需要分别创建它们,最后构建成该复杂对象。
    1.如果创建对象的算法,应该独立于该对象的组成部分以及它们的装配方式时  
    2.如果同一个构建过程有着不同的表示时  

结构型模式

结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合

或聚合来组合对象。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象结构型模式比类结构型模式具有更大的灵活性。
-   适配器(Adapter)模式:将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作。
-   桥接(Bridge)模式:将抽象与实现分离,使它们可以独立变化。它是用组合关系代替继承关系来实现的,从而降低了抽象和实现这两个可变维度的耦合度。
-   组合(Composite)模式:将对象组合成树状层次结构,使用户对单个对象和组合对象具有一致的访问性。
-   装饰(Decorator)模式:动态地给对象增加一些职责,即增加其额外的功能。
-   外观(Facade)模式:为多个复杂的子系统提供一个一致的接口,使这些子系统更加容易被访问。
-   享元(Flyweight)模式:运用共享技术来有效地支持大量细粒度对象的复用。
-   代理(Proxy)模式:为某对象提供一种代理以控制对该对象的访问。即客户端通过代理间接地访问该对象,从而限制、增强或修改该对象的一些特性。
    以上 7 种结构型模式,除了 适配器模式 分为类结构型模式和对象结构型模式两种,其他的全部属于对象结构型模式

1.适配器模式(Adapter)

将一个类的接口转换成客户希望的另外一个接口.适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作. 
    1.如果先要使用一个已经存在的类,但是它的接口不符合你的需求,这种情况可以使用适配器模式,来把已有的实现转换成你需要的接口.
    2.如果你想创建一个可以复用的类,这个类可能和一些不兼容的类一起工作,这中情况可以使用适配器模式,到时候需要什么就适配什么. 
    3.如果你想使用一些已经窜在的子类,但不对每一个子类都进行适配,这中情况可以使用适配器模式,直接适配这些子类的父类就可以了.

2.桥接模式(Bridge)

将抽象部分与它的实现部分分离,使他们可以独立变化. 
    1.如果你不希望在抽象部分和实现部分采用固定的绑定关系,可以采用桥接模式. 
    2.如果出现抽象部分和实现部分都能够扩展的情况,可以采用桥接模式,让抽象部分和实现部分独立地变化. 
    3.如果希望实现部分的修改不会对客户产生影响,可以采用桥接模式. 
    4.如果采用继承的实现方案,会导致产生很多子类,对于这种情况,可以考虑采用桥接模式.

3.组合模式(Composite)

将对象组合成属性结构以表示"部分-整体"的层次结构,组合模式使用的用户对单个对象和组合对象的使用具有一致性. 
    1.如果你想表示对象的部分-整体层次结构,可以使用..把整体和部分的操作统一起来,使得层次结构实现更简单,从外部来使用,这个层次结构也容易. 
    2.如果希望同意地使用组合结构中的所有对象,可以选用,这正是组合模式提供的主要功能.

4.装饰器模式(Decorator Method)

动态的给一个对象增加一些额外的职责,就增加功能来说,装饰模式生成子类更为灵活.

1.如果需要爱不影响其他对象的情况下,以动态,透明的方式给对象添加职责,可以使用装饰模式. 
2.如果不适合使用子类来进行扩展的时候,可以考虑使用装饰模式.

5.外观模式(Facade)

为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层的接口,这个接口使得这一子系统更加同容易使用.
1.如果希望为一个复杂的子系统提供一个简单接口的时候,可以考虑使用外观模式.使用外观对象来实现大部分客户需要的功能,从而简化客户的使用. 
2.如果想要让客户程序和抽象类的实现部分松散耦合,可以考虑使用外观模式,使用外观对象来将这个子系统与他的客户分离开来,从而提高子系统的独立性和可移植性. 
3.如果构建多层节后的系统,可以考虑使用外观模式使用外观模式对象作为每层的入口,这样可以简化层间调用,也可以松散出层次之间的依赖关系.

6.享元模式(Flyweight)

运用共享技术有效地支持大量细粒度的对象. 
    1.如果一个应用程序使用了大量的细粒度对象,可以使用享元模式来减少对象的数量. 
    2.如果犹豫使用大量的对象,造成很大的存储开销,可以使用享元模式来减少对象数量,并节约内存. 
    3.如果对象的大多数状态都可以转变成外部状态,比如通过计算得到,或者从外部传入等,可以使用享元模式来实现内部状态和外部状态的分离.
    4.如果不考虑对象的外部状态,可以用相对较少的共享对象取代很多组合对象,可以使用享元模式来共享对象.然后组合对象来使用这些共享对象.

7.代理模式(Proxy)

 为其他对象提供一种代理以控制对这个对象的访问.
    1.需要为一个对象在不同的地址空间提供局部代表的时候,可以使用远程代理. 
    2.需要按照需要创建开销很大的对象的时候,可以使用虚代理. 
    3.需要控制对原始对象的访问的时候,可以使用保护代理. 
    4.需要在访问你对象执行一些附加操作的时候,可以使用智能指引代理.

行为型模式

行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配。  

行为型模式分为类行为模式和对象行为模式,前者采用继承机制来在类间分派行为,后者采用组合或聚合在对象间分配行为。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象行为模式比类行为模式具有更大的灵活性。  

行为型模式是 设计模式中最为庞大的一类,它包含以下 11 种模式。

-   模板方法(Template Method)模式:定义一个操作中的算法骨架,将算法的一些步骤延迟到子类中,使得子类在可以不改变该算法结构的情况下重定义该算法的某些特定步骤。
-   策略(Strategy)模式:定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的改变不会影响使用算法的客户。
-   命令(Command)模式:将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开。
-   职责链(Chain of Responsibility)模式:把请求从链中的一个对象传到下一个对象,直到请求被响应为止。通过这种方式去除对象之间的耦合。
-   状态(State)模式:允许一个对象在其内部状态发生改变时改变其行为能力。
-   观察者(Observer)模式:多个对象间存在一对多关系,当一个对象发生改变时,把这种改变通知给其他多个对象,从而影响其他对象的行为。
-   中介者(Mediator)模式:定义一个中介对象来简化原有对象之间的交互关系,降低系统中对象间的耦合度,使原有对象之间不必相互了解。
-   迭代器(Iterator)模式:提供一种方法来顺序访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示。
-   访问者(Visitor)模式:在不改变集合元素的前提下,为一个集合中的每个元素提供多种访问方式,即每个元素有多个访问者对象访问。
-   备忘录(Memento)模式:在不破坏封装性的前提下,获取并保存一个对象的内部状态,以便以后恢复它。
-   解释器(Interpreter)模式:提供如何定义语言的文法,以及对语言句子的解释方法,即解释器。

1.策略模式(Strategy)

定义一系列的算法,把它们一个个封装起来,并且使他们可以相互替换.本模式使得算法可独立于使用它的客户而变化. 
    1.出现有许多相关的类,仅仅是行为有差别的情况下,可以使用策略模式来使用多个行为中的一个来配置一个类的方法,实现算法动态切换 
    2.出现同一算法,有很多不同实现的情况下,可以使用策略模式来把这些"不同的实现"实现成为一个算法的类层次. 
    3.需要封装算法中,有与算法相关数据的情况下,可以使用策略模式来避免暴露这些跟算法相关的数据结构. 
    4.出现抽象一个定义了很多行为的类,并且是通过多个if-else语句来选择这些行为的情况下,可以使用策略模式来替换这些条件语句.

2.模版方法模式(TemplateMethod)

定义在一个操作中的算法框架,把一些步骤推迟到子类去实现.模版方法模式让子类不需要改变算法的结构而重新定义特定的算法步骤 
    1.算法的整体步骤很固定,但其中个别部分易变时,这时候可以使用模板方法模式,将容易变的部分抽象出来,供子类实现。

    2.当多个子类存在公共的行为时,可以将其提取出来并集中到一个公共父类中以避免代码重复。首先,要识别现有代码中的不同之处,并且将不同之处分离为新的操作。最后,用一个调用这些新的操作的模板方法来替换这些不同的代码。

    3.当需要控制子类的扩展时,模板方法只在特定点调用钩子操作,这样就只允许在这些点进行扩展。

3.职责链模式(Chain Of Responsibility)

使多个对象都有机会处理请求,,从而避免请求的发送者和接收者之间耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止. 
    1.如果有多个对象可以处理同一个请求,但是具体由哪个对象来处理该请求,是运行时刻动态确定的. 
    2.如果你想在不明确指定接收者的情况下,向多个对象中的其中一个提交请求的话,可以使用职责链模式. 
    3.如果想要动态指定处理一个请求的对象结合,可以使用职责链模式.

4.命令模式(Command)

 将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化,对请求排队或者记录请求日志,以及支持可撤销的操作.

5.解释器模式(Interpreter)

给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子. 使用场合:

6.迭代器模式(Iterator)

提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示. 
    1.如果你希望提供访问一个聚合对象的内容,但是又不想暴露他的内部表示的时候,可以使用迭代器模式来提供迭代器接口,从而让客户端只是通过迭代器的接口来访问聚合对象,而无须关心聚合对象的内部实现. 
    2.如果你希望有多种遍历方式可以访问聚合对象,可以使用
    3.如果你希望为遍历不同的聚合对象提供一个统一的接口,可以使用....

7.中介模式(Mediator)

用一个中介对象类封装一系列对象的交互.中介者使得各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变他们之间的交互. 
1.如果一组对象之间的通信方式比较复杂,导致相互依赖,结构混乱,可以采用中介模式,把这些对象相互的交互管理起来,各个对象都只需要和中介者交互,从而是的各个对象松散耦合,结构也更清晰易懂. 
2.如果一个对象引用很多的对象,并直接跟这些对象交互,导致难以复用该对象,可以采用中介者模式,把这个对象跟其他对象的交互封装到中介者对象里面,这个对象只需要和中介者对象交互就可了.

8.备忘录模式(Memento)

在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将该对象恢复到原先保存的状态. 
    1.如果必须要保存一个对象在某一个时刻的全部或者部分状态,方便以后需要的时候,可以把该对象恢复到先前的状态,可以使用备忘录模式. 
    2.如果需要保存一个对象的内部状态,但是如果用接口来让其他对象直接得到这些需要保存的状态,将会暴露对象的实现希捷并破坏对象的封装性,这是可以使用备忘录.

9.观察者模式(Observer)

定义对象间的一种一对多的依赖关系.当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新. 
    1.当一个抽象模型有两个方面,其中一个方面的操作依赖于另一个方面的状态变化,那么就可以选用观察者模式,将这两者封装成观察者和目标对象,当目标对象变化的时候,依赖于它的观察者对象也会发生相应的变化.这样就把抽象模型的这两个方面分离了使得,它们可以独立地改变和复用. 
    2.如果在更改一个对象的时候,需要同时连带改变其他对象,而且不知道究竟应该有多少对象需要被连带改变,这种情况可以选用观察者模式,被改的那一个对象很明显就相当于是目标对象,而需要连带修改的对歌其他对象,就作为多个观察着对象了. 
    3.当一个对象必须通知其他的对象,但是你又希望这个对象和其他被它通知的对象是松散耦合的,也就是说这个对象其实不详知道具体被通知的对象.这种情况可以选用观察者模式,这个对象就相当于是目标对象,而被它通知的对象就是观察者对象了.

10.状态模式(State)

允许一个对象在其内部状态改变是改变它的行为.对象看起来似乎修改了他的类. 
    1.如果一个对象的行为取决于它的状态,而且它必须在运行时刻根据状态来改变它的行为,可以使用.来包状态和行为分离开.虽然分离了,但是状态和行为是有对应关系的,可以在运行期间,通过改变状态,就能够调用到该状态对应的状态处理对象上去从而改变对象的行为. 
    2.如果一个操作中含有庞大的多分枝语句,而且这些分支依赖于该对象的状态,可以使用
    3.把各个分支的处理分散包装到单独的对象处理类中,这样,这些分支对应的对象就可以不依赖于其他对象而独立变化了.

猜你喜欢

转载自blog.csdn.net/qq_17556191/article/details/95060099