创建型模式 * 5

   (1)单例模式

            动机:确保对象的唯一性(对象内部状态、方法等)

            举例:线程池

            1.1 懒汉式

                   1.1.1 普通实现

                   1.1.2 多线程实现

多线程情况下,由于getInstance方法中存在两次读(一次判断一次返回)操作一                             次写操作(修改intsance变量的值,instance变量为初始化时(即instance=null)
                           可能会存在多个线程进入判断语句,这样该类可能会被实例出多个对象。
                           所以上述实现的懒汉式单例模式是线程不安全的。
                           造成线程不安全的代码段为if语句里面的读操作和instance的修改操作,所以我们                             需要对这段代码进行加锁,然后就得到了线程安全的懒汉模式。

            1.2 饿汉式

            1.3 枚举

动机:单元素的枚举类型已经成为实现Singleton的最佳方法。

   (2)原型模式

            动机:复制一个对象自身

            举例:相似对象编辑

            2.1 深克隆      

            2.1 浅克隆 

   (3)建造者模式

            动机:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表                             示。

            优点:如动机

            缺点:
                      1、建造者模式所创建的产品一般具有较多的共同点,其组成部分相似,如果产品之                         间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制。
                      2、如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变                         化,导致系统变得很庞大。

   (4)简单工厂模式

         动机:源自同一个基类,不过在继承基类后不同的子类修改了部分属性从而使得它们可以呈                      现不同的外观。

         优点:当你需要什么,只需要传入一个正确的参数,就可以获取你所需要的对象,而无须知                      道其创建细节。

         缺点:工厂类的职责相对过重,增加新的产品需要修改工厂类的判断逻辑,这一点与开闭原                      则是相违背的。           

   (5)抽象工厂模式 

          动机:摆脱工厂基类限定,实现对工厂的多态和统一调用管理。

          优点:只需改变具体工厂的实例,就可以在某种程度上改变整个软件系统的行为。

          缺点:在添加新的产品对象时,难以扩展抽象工厂来生产新种类的产品,这是因为在抽象工                       厂角色中规定了所有可能被创建的产品集合,要支持新种类的产品就意味着要对该接                       口进行扩展,而这将涉及到对抽象工厂角色及其所有子类的修改,显然会带来较大的                       不便。

结构型模式 * 8

   (1)享元模式 

          动机:通过共享技术实现相同或相似对象的重用。

          优点:(1)享元模式的优点在于它可以极大减少内存中对象的数量,使得相同对象或相似                         对象在内存中只保存一份。
                     (2)享元模式的外部状态相对独立,而且不会影响其内部状态,从而使得享元对象                         可以在不同的环境中被共享。

          缺点:

                     (1)享元模式使得系统更加复杂,需要分离出内部状态和外部状态,这使得程序的                         逻辑复杂化。
                     (2)为了使对象可以共享,享元模式需要将享元对象的状态外部化,而读取外部状                         态使得运行时间变长。

   (2)代理模式

            动机:

                一个客户不想或者不能直接引用一个对象,

                此时可以通过一个称之为“代理”的第三者来实现间接引用。

            优点:代理模式能够协调调用者和被调用者,在一定程度上降低了系统的耦合度。

            缺点:

              (1)由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造                         成请求的处理速度变慢。
              (2)实现代理模式需要额外的工作,有些代理模式的实现非常复杂。

   (3)外观模式(门面模式)

            动机:用户只需要直接与外观(门面)角色交互,用户与子系统之间的复杂关系由外观角                         色来实现。

            优点:对客户屏蔽子系统组件,减少了客户处理的对象数目并使得子系统使用起来更加容                         易。

            缺点:不能很好地限制客户使用子系统类,如果对客户访问子系统类做太多的限制则减少                        了可变性和灵活性。
                       在不引入抽象外观类的情况下,增加新的子系统可能需要修改外观类或客户端的源                         代码,违背了“开闭原则”。

   (4)适配器模式

           动机:适配器可以使由于接口不兼容而不能交互的类可以一起工作。

            4.1 对象适配器      

                  优点:同一个适配器可以把适配者类和它的子类都适配到目标接口。

                  缺点:置换适配者类的方法就不容易。

            4.2 类适配器           

                  优点:由于适配器类是适配者类的子类,因此可以在适配器类中置换一些适配者的方                                 法,使得适配器的灵活性更强。

                  缺点:单继承,受制于java语言底层,一次最多只能适配一个适配者类。

   (5)桥接模式

                  动机:对于有多个维度(多个变化原因)而组成的系统中的子模块。

                             相较于N*N的组合,设计系统中类的个数更少,且系统扩展更为方便。

                  动机详细:

                             理解桥接模式,重点需要理解如何将抽象化(Abstraction)与实现化                                                     (Implementation)脱耦,使得二者可以独立地变化。
                             抽象化:

                                 抽象化就是忽略一些信息,把不同的实体当作同样的实体对待。

                                 在面向 对象中,将对象的共同性质抽取出来形成类的过程即为抽象化的过                                       程。
                             实现化:

                                 针对抽象化给出的具体实现,就是实现化,

                                 抽象化与实现化是一对互逆的概念,实现化产生的对象比抽象化更具体,

                                 是对抽象化事物的进一步具体化的产物。
                             脱耦:

                                  脱耦就是将抽象化和实现化之间的耦合解脱开,或者说是将它们之间的强关                                    联改换成弱关联,将两个角色之间的继承关系改为关联关系。桥接模式中的                                    所谓脱耦,就是指在一个软件系统的抽象化和实现化之间使用关联关系(组                                    合或者聚合关系)而不是继承关系,从而使两者可以相对独立地变化,这就                                    是桥接模式的用意。
 

                  优点:桥接模式是比多继承方案更好的解决方法。

                  缺点:桥接模式的引入会增加系统的理解与设计难度,

                             桥接模式要求正确识别出系统中两个独立变化的维度,因此其使用范围具有一                                 定的局限性。

   (6)组合模式

                  动机:树形结构对象处理

                  优点:定义了包含叶子对象和容器对象的类层次结构,叶子对象可以被组合成更复杂                                 的容器对象,而这个容器对象又可以被组合,这样不断递归下去,可以形成复                                 杂 的树形结构。

                  缺点:不是所有的方法都与叶子对象子类都有关联,整体维护复杂。

   (7)装饰模式

                  动机:        

                  一般有两种方式可以实现给一个类或对象增加行为:
               (1)继承机制,使用继承机制是给现有类添加功能的一种有效途径,通过继承一个现有                          类可以使得子类在拥有自身方法的同时还拥有父类的方法。但是这种方法是静态                              的,用户不能控制增加行为的方式和时机。
               (2)关联机制,即将一个类的对象嵌入另一个对象中,由另一个对象来决定是否调用嵌                         入对象的行为以便扩展自己的行为,我们称这个嵌入的对象为装饰器(Decorator)。

                       装饰模式以对客户透明的方式动态地给一个对象附加上更多的责任,换言之,客户                        端并不会觉得对象在装饰前和装饰后有什么不同。装饰模式可以在不需要创造更多                          子类的情况下,将对象的功能加以扩展。这就是装饰模式的模式动机。

                   优点:如动机

                   缺点:这种比继承更加灵活机动的特性,也同时意味着装饰模式比继承更加易于出                                    错,排错也很困难

行为型模式 * 11

   (1)中介者模式 

            动机:基于一件客观事务的需要消息触发的流程事实。中介者对象负责获取消息,得到消                         息后,按照流程事实进行处理。消息的发送方和接收方是放在中介者内部进行统一                          调度的。

            优点:简化了对象之间的交互。

            缺点:在具体中介者类中包含了同事之间的交互细节,可能会导致具体中介者类非常复                             杂,使得系统难以维护。

   (2)命令模式

            动机:基于一件客观事务的需要消息触发的流程事实。但流程中的细节不由消息发送方掌                         控,而由接收方进行自我编排。

            优点:可以比较容易地设计一个命令队列。

            缺点:某些复杂业务场景,命令类的横向扩展较多,不好维护。

   (3)备忘录模式

             动机:快速回退对象状态。

             优点:提供了一种状态恢复的实现机制,使得用户可以方便地回到一个特定的历史步骤。

             缺点:资源消耗过大,如果类的成员变量太多,就不可避免占用大量的内存。

   (4)状态模式

            动机:允许状态转换逻辑与状态对象合成一体,而不是某一个巨大的条件语句块。

            优点:如动机

            缺点:状态模式的使用必然会增加系统类和对象的个数。
                       状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱。

   (5)策略模式(政策模式(Policy))

            动机:让算法独立于使用它的客户而变化

            优点:

                      避免使用多重条件转移语句if。

                      提供了管理相关的算法族的办法。

                      提供了对“开闭原则”的完美支持,可以灵活地增加新的算法或行为。

            缺点:

                      客户端必须知道所有的策略类,并自行决定使用哪一个策略类。
                      策略模式将造成产生很多策略类,可以通过使用享元模式在一定程度上减少对象的                          数量。          

   (6)职责链模式

            动机:将请求的处理者组织成一条链,并使请求沿着链传递,由链上的处理者对请求进行                         相应的处理。职责链可以是一条直线、一个环或者一个树形结构。

            优点:如动机

            缺点:

                   (1)不能保证请求一定被接收。
                   (2)系统性能将受到一定影响,而且在进行代码调试时不太方便;可能会造成循环调                              用。

   (7)观察者模式

            动机:建立一种对象与对象之间的依赖关系,一个对象发生改变时将自动通知其他对象,                        其他对象将相应做出反应。

            优点:支持广播通信。符合“开闭原则”的要求。

            缺点:如果观察者多,则时间复杂度大。如果是环状,则可能系统崩溃。发生变化这个动                         作,观察者无法知道。

   (8)访问者模式

            动机:可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

            优点:如动机

            缺点:增加新的元素类很困难,破坏封装,维护麻烦。

   (9)迭代器模式

            动机:树形对象的封装

            优点:它支持以不同的方式遍历一个聚合对象。
                      迭代器简化了聚合类。
                      在同一个聚合上可以有多个遍历。
                      在迭代器模式中,增加新的聚合类和迭代器类都很方便,无须修改原有代码,满足                          “开闭原则”的要求。

            缺点:遍历数据的方法被单独抽出:由于迭代器模式将存储数据和遍历数据的职责分离,                         增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上                         增加了系统的复杂性。

   (10)模板方法模式

            动机:不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实                             现。

            优点:如动机

            缺点:子类在业务场景较复杂的情景下横向扩展多,不易于维护。

   (11)解释器模式

            动机:如果在系统中某一特定类型的问题发生的频率很高,此时可以考虑将这些问题的实                         例表述为一个语言中的句子。

            优点:

                       易于改变和扩展文法。
                       易于实现文法。
                       增加了新的解释表达式的方式。

            缺点: 

                       对于复杂文法难以维护。
                       执行效率较低。
                       应用场景很有限。