设计模式总体概述

创建型模式

  • 单例模式
    • 定义:确保一个类只有一个实例,提供全局访问点。
    • 目的:使得在操纵该对象时始终只是该实例,防止资源的浪费
    • 个人理解:就是一个对象只能被创建一次,在定义的范围内只存在唯一的一个。从被创建到被销毁,不存在和他一样的对象。
    • uml图:
    • 实现形式:
public class Singleton {   
              //volatile保证,当uniqueInstance变量被初始化成Singleton实例时,多个线程可以正确处理uniqueInstance变量
                private volatile static Singleton uniqueInstance;
                private Singleton() {
                }
                public static Singleton getInstance() {
                   //检查实例,如果不存在,就进入同步代码块
                    if (uniqueInstance == null) {
                        //只有第一次才彻底执行这里的代码
                        synchronized(Singleton.class) {
                           //进入同步代码块后,再检查一次,如果仍是null,才创建实例
                            if (uniqueInstance == null) {
                                uniqueInstance = new Singleton();
                            }
                        }
                    }
                    return uniqueInstance;
                }
         }
  • 原型模式
    • 定义:用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型相同或相似的新对象。
    • 目的:
    • 个人理解:就是调用者希望获取到一个实例的复制品(可以根据自己需求选择时浅拷贝或者是深拷贝),当然调用者可能并不是要直接使用该复制品,有时候只是因为需要的实例与原有的实例有很大的相似性,获取到原有实例的复制品之后对某些属性进行修改就可以获得想要的结果。
    • uml: e8c8a6faaade4fc9658bb29915444b45.png
  • 工厂方法模式:
    • 定义:定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体子工厂类当中。
    • 目的:
    • 个人理解:通过具体的工厂获取到工厂中生产的对应的产品,就像从海尔的工厂中获取到海尔空调,而从美菱的工厂中获取到美菱空调一样。
    • uml: d8e51b3adf3077780db33b2e5c527269.png
  • 抽象工厂模式:
    • 定义:是一种为访问类提供一个创建一组相关或相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构。
    • 目的:抽象工厂模式是工厂方法模式的升级版本,工厂方法模式只生产一个等级的产品,而抽象工厂模式可生产多个等级的产品。
    • 个人理解: 通过具体的工厂获取到工厂中生产的对应的产品,但此时每个工厂不仅仅只是生产一种产品,而是生产多种类型的产品,就像从海尔的工厂中获取到海尔空调与冰箱,而从美菱的工厂中获取到美菱空调与美菱冰箱一样。
    • uml:ef29430f1209049432af83c18fc5a9fc.png
  • 建造者模式:
    • 定义:指将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式。
    • 目的:将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成。它将变与不变相分离,即产品的组成部分是不变的,但每一部分是可以灵活选择的。
    • 个人理解: 当需要去建造某种产品时,通过指挥者即可以选择产品的创建者,从而获取到相应的产品,也就是调用者不需要关系创建过程,只需要等待指挥者来返回产品即可
    • uml:ae769e3342e768e8ae25a2a29b52e577.png

结构型模式

  • 适配器模式:
    • 定义:将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作。
    • 目的:解决业务系统调用中出现的不兼容问题。
    • 个人理解:适配器分为两种,类适配器与对象适配器。两者的区别在于前者为了适配而将适配者作为适配器的父类,而后者是将适配者作为适配器的一个成员变量。
    • uml:前者是类适配器,后者是对象适配器
      373781fe4a1b365295527e7bc6d2aa04.png
      286e901ea06472302e3a6c4a7db61836.png
  • 桥接模式:
    • 定义:将抽象与实现分离,使它们可以独立变化。
    • 目的:用组合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度。
    • 个人理解:当我们想要画图时,有两者维度,颜色与形状,我们怎么去实现不同颜色与不同形状的图呢?如果采用继承方式那么将会是颜色数量与形状数量的乘积,这时候我们可以把形状作为一个成员变量,这样我们继承了颜色,又包含了形状,从而实现了我们想要的结果图。
    • uml:136e42a1fe0835838be2ee2ee8d8010c.png
  • 代理模式:
    • 定义:由于某些原因需要给某对象提供一个代理以控制对该对象的访问。
    • 目的:访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。
    • 个人理解:代理模式的结果是去扩展原有的功能,但扩展功能的本质不属于原对象本身,而是属于代理对象,也就是在原对象本身包了一层,就好像一个人去买房子,只需要付钱,其他的诸如房子的分析,手续的办理都交给中介即可。
    • uml:15670a949cb9389549758214ea03657e.png
  • 装饰模式:
    • 定义:指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式,它属于对象结构型模式。
    • 目的:使用组合关系来创建一个包装对象(即装饰对象)来包裹真实对象,并在保持真实对象的类结构不变的前提下,为其提供额外的功能。
    • 个人理解:通过装饰器的层层包裹使得原对象的功能大大提升。与代理模式相比,装饰器模式更加灵活,可以去层层包裹,需要什么功能就去添加什么功能,且其功能主体还是原有对象,其余功能只是对该对象的补充,而代理模式其进行功能的主体变成了代理对象,原有主体相当于是代理对象的一种属性。
    • uml:7912063b425133a5eee541abdba1a4de.png
  • 外观模式:
    • 定义: 是一种通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式。
    • 目的: 对外有一个统一接口,外部应用程序不用关心内部子系统的具体的细节,这样会大大降低应用程序的复杂度,提高了程序的可维护性。
    • 个人理解:就像是现在的综合办公大厅,不需要去派出所、交通局、教育局等多个职能部门跑,而是直接在这么一个大厅就可以实现所有的功能。接下来即使成立更多的职能部门,只需要将其对应的功能放入综合办公大厅即可
      -uml:40428b1ee6c747b798eb766e56118bda.png
  • 享元模式:
    • 定义:运用共享技术来有効地支持大量细粒度对象的复用。
    • 目的:它通过共享已经存在的又橡来大幅度减少需要创建的对象数量、避免大量相似类的开销,从而提高系统资源的利用率。
    • 个人理解:在享元工厂中利用map去存储相应的key与其对应的对象,我们默认key不同则对象不同,那么获取时判断key是否存在,存在则直接返回对应的对象,不存在则把key与对象存入。
    • uml:790324d2fea10eb5c755aa8b49187c92.png
  • 组合模式:
    • 定义:有时又叫作部分-整体模式,它是一种将对象组合成树状的层次结构的模式,用来表示“部分-整体”的关系,使用户对单个对象和组合对象具有一致的访问性。
    • 目的:去实现同种类型对象之间的关系。
    • 个人理解:为了把多个对象组合成树的结构,利用树叶与树枝两种角色,树叶即对象,树枝即存放多个对象的容器。通过树叶与树枝的组合来形成一棵树。
    • uml:前者透明方式(客户端无须区别树叶对象和树枝对象,对客户端来说是透明的),后者安全方式(叶构件本来没有 Add()、Remove() 及 GetChild() 方法,却要实现它们(空实现或抛异常),这样会带来一些安全性问题)。
      04afdd77b392aa3e9726050f525a0f36.png
      2f44a72f4686282dcf259c872d0cb6a7.png

行为型模式

  • 模板方法模式:

    • 定义 :定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。
    • 目的:
    • 个人理解:模板就是给行为定义大致路径,具体的情况需要自己实现。就好比去银行办理业务一般要经过以下4个流程:取号、排队、办理具体业务、对银行工作人员进行评分等,其中取号、排队和对银行工作人员进行评分的业务对每个客户是一样的,可以在父类中实现,但是办理具体业务却因人而异,它可能是存款、取款或者转账等,可以延迟到子类中实现。
    • uml:ff5deff5b67611ef291b6027f6f3d24c.png
  • 策略模式:

    • 定义:该模式定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。
    • 目的:它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。
    • 个人理解:其实策略模式与模板方法很像,都是去定义一个框架,具体的方法需要根据需要的情况来实现。但模板方法所侧重的是定义某一个行为链的整体结构,而行为链上的具体节点需要调用者自主实现。而策略模式的重点在于对某个算法进行抽象,而具体的实现需要调用者来实现。
    • uml:762cd7277d163a20014b6cf971afd5b3.png
  • 命令模式:

    • 定义:将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开。
    • 目的:这样两者之间通过命令对象进行沟通,这样方便将命令对象进行储存、传递、调用、增加与管理。
    • 个人理解:既然把命令进行了封装,也就是说对于发送者,接受者或者中转者来说,都是一个抽象的概念,而当我们真正去传递一个被实现的具体的命令时,对于这个命令模式的整体框架是没什么区别的。所以对于接受者与发送者都是对抽象命令这个对象进行操作,就不需要在乎具体实现,可以实现接受者与发送者的灵活抽插。
    • uml:9c3ad5566b55a50858bdf815ecdc440e.png
  • 责任链模式:

    • 定义:为了避免请求发送者与多个请求处理者耦合在一起,将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止。
    • 目的:在责任链模式中,客户只需要将请求发送到责任链上即可,无须关心请求的处理细节和请求的传递过程,所以责任链将请求的发送者和请求的处理者解耦了。
    • 个人理解:责任链就像在公司里,我们每个人都会有一个直系leader,而leader也会有他的大leader,我们不需要去管我们leader的大leader是谁,只需要把我们的工作向直系leader汇报,而leader会不会向他的大leader汇报我们不需要去管,只需要做好我们自己的本职工作就好了。
    • uml:fc87d8abb8bd764d0ec8e77d6546b203.png
  • 状态模式:

    • 定义:对有状态的对象,把复杂的“判断逻辑”提取到不同的状态对象中,允许状态对象在其内部状态发生改变时改变其行为。
    • 目的:状态模式把受环境改变的对象行为包装在不同的状态对象里,其意图是让一个对象在其内部状态改变的时候,其行为也随之改变。现在我们来分析其基本结构和实现方法。
    • 个人理解:把对象的状态进行抽象化成为一个状态对象,当我们通过操作修改了当前对象时,这个对象就变成了之后的状态对象,而不是一个原始的对象,所谓的状态变化其实也就是状态对象直接的变化。其缺点很明显,就是如果状态很多,就会出现很多的状态对象类。
    • uml:055c1279f1d3614f07c54ccb460ffa30.png
  • 观察者模式:

    • 定义:指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
    • 目的:
    • 个人理解:观察者,观察的就是目标或者说主题的变动,一旦发生变动就要相应的作出应答,这就需要观察者向目标注册,从而在目标发生变动时目标可以去通知已经注册的观察者,从而使观察者进行相应的response。
    • uml:1a28cd43c7b2b6d6bb3c5eee3eae7f07.png
  • 中介者模式:

    • 定义:定义一个中介对象来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互。
    • 目的:将对象间的一对多关联转变为一对一的关联,提高系统的灵活性,使得系统易于维护和扩展。
    • 个人理解:同事类注册到中介上,从而让其它同事类可以通过中介进行彼此的关联。这与观察者很像,都有个类似中台的角色,不过两者的目的不同。观察者模式中观察者与主题的关系是一种单向的关系,即主题知道他的观察者,观察者却不知道自己已经注册了的主题,这是因为观察者模式的目的是为了当主题发生变化时观察者可以被动进行相应的操作,而不是观察者会主动进行某种操作。而中介者模式中同事与中介的关系一种双向的关系,彼此都知道对方的存在,也就是同事知道他的中介,中介也知道以及在他身上注册的同事,这是因为中介的模式是为了让同事去认识更多的同事,而且可以通过中介让其他同事去做一些事情,在这个关系中,平台处于被动的状态,而同事既作为主动发起者,也做为被动的反馈者。
    • uml:9dd01efefaf98828bbbeff1ada4af3cd.png
  • 迭代器模式:

    • 定义:提供一个对象来顺序访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示。
    • 目的:迭代器模式是通过将聚合对象的遍历行为分离出来,抽象成迭代器类来实现的,其目的是在不暴露聚合对象的内部结构的情况下,让外部代码透明地访问聚合的内部数据。
    • 个人理解:是对元素遍历方法的封装,客户端在调用的时候不需要去真正认识到元素集合的内部排列方式以及其真正的元素遍历方式,只需要去获取到元素集合的迭代器,通过迭代器的统一方法进行遍历的调用即可。而我们只需要在建立集合的之后为其封装其对应的迭代器即可。这样当客户端调用的集合发生了变化,我们不需要对主程序进行变化,只需要将集合进行替代,其他的代码无需任何变化。
    • uml:76403048a36c47b00c608c24fbdd46a0.png
  • 访问者模式:

    • 定义:将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的新的操作,为数据结构中的每个元素提供多种访问方式。
    • 目的:把处理方法从数据结构中分离出来,并可以根据需要增加新的处理方法,且不用修改原来的程序代码与数据结构,这提高了程序的扩展性和灵活性。
    • 个人理解:对于某种数据结构,它只提供了对外的数据展示接口,而什么对象去调用都会是同样的数据,这样的目的是为了保证该数据结构不会发生变化,那么我们如何对于这些数据进行操作呢?这就需要我们对相应的数据结构提供相应的数据处理方式,从而可以灵活的对数据进行操作,不需要在该数据结构内部进行操作的添加。这就和迭代器模式很像,迭代器模式是对集合数据的遍历操作进行封装,通过迭代器的形式进行统一的遍历,从而不论集合结构如何改变,只要保证最外层在调用的时候调用的是当前集合的迭代器就行了,至于到底是什么集合,这对我们是透明的,我们不需要关心。而访问者模式中,访问者每次访问的数据是相同的,不论访问者访问多少次,不同的访问者对于某个元素的访问结果必然是相同的。这就使得在我们实现对数据的操作也就是对访问者的定义时,不需要关心数据的变化,只需要同样的调用数据,然后实现想要的功能即可。
    • uml:bbcf1c5eb05ed2d530145432a414a9ed.png
  • 备忘录模式:

    • 定义:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后当需要时能将该对象恢复到原先保存的状态。
    • 目的:记录一个对象的内部状态,当用户后悔时能撤销当前操作,使数据恢复到它原先的状态。
    • 个人理解:备忘录即快照,当我们为了能够以后可以反悔,就把当前的状态保存为快照存起来,那么存到哪里去呢?这就需要一个管理者来存储快照,从而当我们想要反悔时,通过管理者获取到之前的快照然后把当前对象进行恢复就可以了。不过这里有个问题,为什么我们不能把这个快照存储在当前对象中?如果我们把对象的快照作为对象的一个属性,那么我岂不是可以一直沿着快照寻找到最初的状态?或者直接把管理者作为发起者的一个属性,那么岂不是可以达到同样的效果?如果我们在管理者中存储多个状态,这样不是可以达到多状态备份?
    • uml:前者就是通过备忘录存储状态,而后者就是通过发起人本身保存发起人的状态(集合原型模式)
      33e3a6b3c0f26155ca960eac457d40ac.png
      ca4f7806cfaf4f8395f15a03552c509a.png
  • 解释器模式:

    • 定义:给分析对象定义一个语言,并定义该语言的文法表示,再设计一个解析器来解释语言中的句子。
    • 目的:用编译语言的方式来分析应用中的实例。
    • 个人理解:
    • uml:216ee93a8029e4b13b2bbdfb26c3c1f4.png
posted @ 2019-08-16 15:06  慵懒的仙人掌  阅读(150)  评论(0编辑  收藏  举报