前言

软件开发越来越复杂,对软件设计的要求也越来越高,而软件设计和架构的入门功夫就是深入理解和掌握设计模式。因此,设计模式的重要性不言而喻。

很多朋友认识到了设计模式的重要性,也看了很多的书籍和资料,但是,常听到这样的抱怨:“ 设计模式的书我看了不少,觉得都看懂了,就是不知道在实际开发中怎么运用这些设计模式”,从而认为设计模式是"看上去很美的花拳绣腿”。

其实不然,造成这种情况的原因就在于:这些朋友对设计模式的理解不到位,自己感觉懂了,其实还差很远,并没有“真正”理解和掌握设计模式。

本文就针对这种情况,让大家真正理解和掌握23种设计模式,并且能够灵活运用,希望大家能够喜欢!!!

 

目录

 

主要内容

第1章设计模式基础, 什么是模式?从字面上理解,模,就是模型、模板的意思:式,就是方式、方法的意思。综合起来,所谓模式就是:可以作为模型或模板的方式或方法。再简单点说就是可以用来作为样板的方式或方法,类似于大家所熟悉的范例。

按照上面的理解,设计模式指的就是设计方面的模板,也即设计方面的方式或方法。

设计模式:是指在软件开发中,经过验证的,用于解决在特定环境下、重复出现的、特定问题的解决方案。

 

第2章简单工厂,简单工厂不是一一个标准的设计模式,但是它实在是太常用了,简单而又神奇,所以需要好好掌握它,就当是学习设计模式的热身运动吧。为了保持一致性,我们尽量按照学习其他模式的步骤来进行学习。

 

第3章外观模式,外观模式有如下优点。

  • 松散耦合:外观模式松散了客户端与子系统的耦合关系,让子系统内部的模块能更容易扩展和维护。
  • 简单易用:外观模式让子系统更加易用,客户端不再需要了解子系统内部的实现,也不需要跟众多子系统内部的模块进行交互,只需要跟外观交互就可以了,相当于外观类为外部客户端使用子系统提供了一站式服务。
  • 更好地划分访问的层次:通过合理使用Facade,可以帮助我们更好地划分访问的层次。有些方法是对系统外的,有些方法是系统内部使用的。把需要暴露给外部的功能集中到外观中,这样既方便客户端使用,也很好地隐藏了内部的细节。

 

 

第4章适配器模式(Adapter),适配器模式有如下优点。

  • 更好的复用性:如果功能是已经有了的,只是接口不兼容,那么通过适配器模式就可以让这些功能得到更好的复用。
  • 更好的可扩展性:在实现适配器功能的时候,可以调用自己开发的功能,从而自然地扩展系统的功能。

 

 

第5章单例模式(Singleton),

1.单例模式的功能

单例模式是用来保证这个类在运行期间只会被创建一一个类实例,另外,单例模式还提供了一个全局唯一访 问这个类实例的访问点,就是getInstance 方法。不管采用懒汉式还是饿汉式的实现方式,这个全局访问点是一一样的。

对于单例模式而言,不管采用何种实现方式,它都是只关心类实例的创建问题,并不关心具体的业务功能。

2.单例模式的范围

也就是在多大范围内是单例呢?

观察上面的实现可以知道,目前Java里面实现的单例是一个虚拟机的范围。因为装载类的功能是虚拟机的,所以一个虚拟机在通过自己的ClassLoader装载饿汉式实现单例类的时候就会创建一个类的实例。

 

第6章方法模式(Factory Method)

工厂方法模式的功能

工厂方法模式的主要功能是让父类在不知道具体实现的情况下,完成自身的功能调用:而具体的实现延迟到子类来实现。

这样在设计的时候,不用去考虑具体的实现,需要某个对象,把它通过工厂方法返,回就好了,在使用这些对象实现功能的时候还是通过接口来操作,这类似于IoC/DI的思想,这个在后面将给大家稍详细点介绍。

 

第7章抽象工厂模式(Abstract Factory)

抽象工厂模式的功能

抽象工厂的功能是为一系列相关对象或相互依赖的对象创建一-个接口。一 *定要注意,这个接口内的方法不是任意堆砌的,而是一系列相关或相互依赖的方法,比如上面例子中的CPU和主板,都是为了组装一台电脑的相关对象。

从某种意义上看,抽象工厂其实是一个产品系列,或者是产品簇。上面例子中的抽象工厂就可以看成是电脑簇,每个不同的装机方案,代表- -种具体的电脑系列。

 

第8章生成器模式(Builder)

生成器模式的主要功能是构建复杂的产品,而且是细化的、分步骤的构建产品,也就是生成器模式重在一步一步解决构造复杂对象的问题。如果仅仅这么认识生成器模式的功能是不够的。

再直白点说,生成器模式的重心在于分离构建算法和具体的构造实现,从而使得构建算法可以重用。具体的构造实现可以很方便地扩展和切换,从而可以灵活地组合来构造出不同的产品对象。

 

第9章原型模式(Prototype)

原型模式的功能实际上包含两个方面:

  • 一个是通过克隆来创建新的对象实例;
  • 另一个是为克隆出来的新的对象实例复制原型实例属性的值。

原型模式要实现的主要功能就是:通过克隆来创建新的对象实例。一般来讲,新创建出来的实例的数据是和原型实例一样的。但是具体如何实现克隆,需要由程序自行实现,原型模式并没有统-的要求和实现算法。

 

第10章中介者模式(Mediator)

中介者的功能非常简单,就是封装对象之间的交互。如果一个对象的操作会引起其他相关对象的变化,或者是某个操作需要引起其他对象的后续或连带操作,而这个对象又不希望自己来处理这些关系,那么就可以找中介者,把所有的麻烦扔给它,只在需要的时候通知中介者,其他的就让中介者去处理就可以了。

反过来,其他的对象在操作的时候,可能会引起这个对象的变化,也可以这么做。

最后对象之间就完全分离了,谁都不直接跟其他对象交互,那么相互的关系全部被集中到中介者对象里面了,所有的对象就只是跟中介者对象进行通信,相互之间不再有联系。

把所有对象之间的交互都封装在中介者当中,无形中还可以得到另外一个好处,就是能够集中地控制这些对象的交互关系,这样当有变化的时候,修改起来就很方便。

 

第11章代理模式(Proxy)

代理模式是通过创建- -个代理对象,用这个代理对象去代表真实的对象,客户端得到这个代理对象后,对客户端并没有什么影响,就跟得到了真实对象一样来使用。

当客户端操作这个代理对象的时候,实际上功能最终还是会由真实的对象来完成,只不过是通过代理操作的,也就是客户端操作代理,代理操作真正的对象。

正是因为有代理对象夹在客户端和被代理的真实对象中间,相当于-一个中转,那么在中转的时候就有很多花招可以玩,比如,判断一下权限,如果没有足够的权限那就不给你中转了。

 

第12章观察者模式(Observer)

按照模式的定义,目标和观察者之间是典型的一对多的关系。

但是要注意,如果观察者只有一一个,也是可以的,这样就变相实现了目标和观察者之间一-对--的关系,这也使得在处理-一个对象的状态变化会影响到另一个对象的时候,也可以考虑使用观察者模式。

同样地,一个观察者也可以观察多个目标,如果观察者为多个目标定义的通知更新方法都是update方法的话,这会带来麻烦,因为需要接收多个目标的通知,如果是一一个update的方法,那就需要在方法内部区分,到底这个更新的通知来自于哪一个目标,不同的目标有不同的后续操作。

一般情况下,观察者应该为不同的观察者目标定义不同的回调方法,这样实现最简单,不需要在update方法内部进行区分。

 

第13章命令模式(Command)

1. 命令模式的关键

命令模式的关键之处就是把请求封装成为对象,也就是命 令对象,并定义了统一的执行操作的接口,这个命令对象可以被存储、转发、记录、处理、撤销等,整个命令模式都是围绕这个对象在进行。

2.命令模式的组装和调用

在命令模式中经常会有一个命令的组装者,用它来维护命令的“虚”实现和真实实现之间的关系。如果是超级智能的命令,也就是说命令对象自己完全实现好了,不需要接收者,那就是命令模式的退化,不需要接收者,自然也不需要组装者了。

而真正的用户就是具体化请求的内容,然后提交请求进行触发就可以了。真正的用户会通过Invoker来触发命令。

在实际开发过程中,Client 和Invoker可以融合在一起,由客户在使用命令模式的时候,先进行命令对象和接收者的组装,组装完成后,就可以调用命令执行请求。

 

第14章迭代器模式(terator)

迭代器模式的功能主要在于提供对聚合对象的迭代访问。迭代器就围绕着这个“访问”做文章,延伸出很多的功能来。比如:以不同的方式遍历聚合对象,比如向前、向后等。

■对同一个聚合同时进行多个遍历。

■以不同的遍历策略来遍历聚合,比如是否需要过滤等。

多态迭代,含义是:为不同的聚合结构提供统的迭代接口,也就是说通过一个迭代接口可以访问不同的聚合结构,这就叫做多态迭代。上面的示例就 已经实现了多态迭代。事实上,标准的迭代模式实现基本上都是支持多态迭代的。

 

第15章组合模式(Composite)

组合模式的目的是:让客户端不再区分操作的是组合对象还是叶子对象,而是以一个统-一的方式来操作。

实现这个目标的关键之处,是设计一个抽象的组件类,让它可以代表组合对象和叶子对象。这样一来,客户端就不用区分到底操作的是组合对象还是叶子对象了,只需要把它们全部当作组件对象进行统一-的操作就可以 了。

 

第16章模板方法模式(Template Method)

模板方法模式的功能在于固定算法骨架,而让具体算法实现可扩展。

这在实际应用中非常广泛,尤其是在设计框架级功能的时候非常有用。框架定义好了算法的步骤,在合适的点让开发人员进行扩展,实现具体的算法。比如在DAO实现中设计通用的增删改查功能,这个在后面会给大家示例。

模板方法模式还额外提供了-一个好处,就是可以控制子类的扩展。因为在父类中定义好了算法的步骤,只是在某几个固定的点才会调用到被子类实现的方法,因此也就只允许在这几个点来扩展功能。这些可以被子类覆盖以扩展功能的方法通常被称为“钩子”方法,在后面也会给大家示例。

 

第17章策略模式(Strategy)

策略模式的功能是把具体的算法实现从具体的业务处理中独立出来,把它们实现成为单独的算法类,从而形成一系列的算法,并让这些算法可以相互替换。

策略模式的重心不是如何来实现算法,而是如何组织、调用这些算法,从而让程序结构更灵活,具有更好的维护性和扩展性。

 

第18章状态模式(State)

所谓对象的状态,通常指的就是对象实例的属性的值:而行为指的就是对象的功能,再具体点说,行为大多可以对应到方法上。

状态模式的功能就是分离状态的行为,通过维护状态的变化,来调用不同状态对应的不同功能。

也就是说,状态和行为是相关联的,它们的关系可以描述为:状态决定行为。

由于状态是在运行期被改变的,因此行为也会在运行期根据状态的改变而改变,看起来,同一一个对象,在不同的运行时刻,行为是不样的,就像是类被修改了一样。

 

第19章备忘录模式(Memento)

备忘录模式的功能,首先是在不破坏封装性的前提下,捕获一个对象的内部状态。

这里要注意两点,一个是不破坏封装性,也就是对象不能暴露它不应该暴露的细节;另外一个是捕获的是对象的内部状态,而且通常还是运行期间某个时刻对象的内部状态。

为什么要捕获这个对象的内部状态呢?捕获这个内部状态有什么用呢?

 

第20章享元模式(Flyweight)

享元模式设计的重点就在于分离变与不变。把一个对象的状态分成内部状态和外部状态,内部状态是不变的,外部状态是可变的。然后通过共享不变的部分,达到减少对象数量并节约内存的目的。在享元对象需要的时候,可以从外部传入外部状态给共享的对象,共享对象会在功能处理的时候,使用自己内部的状态和这些外部的状态。

事实上,分离变与不变是软件设计上最基本的方式之一一,比如预留接口,为什么在这个地方要预留接口,-一个常见的原因就是这里存在变化,可能在今后需要扩展或者是改变已有的实现,因此预留接口作为“可插入性的保证”。

 

第21章解释器模式(Interpreter)

解释器模式使用解释器对象来表示和处理相应的语法规则,一般一 个解释 器处理一条语法规则。理论上来说,只要能用解释器对象把符合语法的表达式表示出来,而且能够构成抽象的语法树,那都可以使用解释器模式来处理。

 

第22章装饰模式(Decorator)

装饰模式能够实现动态地为对象添加功能,是从一个对象外部来给对象增加功能,相当于是改变了对象的外观。当装饰过后,从外部使用系统的角度看,就不再是使用原始的那个对象了,而是使用被- - 系列的装饰器装饰过后的对象。

这样就能够灵活地改变-一个对 象的功能,只要动态组合的装饰器发生了改变,那么最终所得到的对象的功能也就发生了改变。

变相地还得到了另外-一个好处,那就是装饰器功能的复用,可以给一个对象多次增加同一个装饰器,也可以用同一个装饰器装饰不同的对象。

 

第23章职责链模式(Chain of Responsibility)

职责链模式主要用来处理“客户端发出一个请求,有多个对象都有机会来处理这一个请求,但是客户端不知道究竟谁会来处理他的请求”这样的情况。也就是需要让请求者和接收者解耦,这样就可以动态地切换和组合接收者了。

如果要变形使用职责链,就可以让这个请求继续传递,每个职责对象对这个请求进行一定的功能处理,从而形成--个处理请求的功能链。

 

第24章桥接模式(Bridge)

在桥接模式中,不太好理解的就是桥接的概念。什么是桥接?为何需要桥接?如何桥接?把这些问题搞清楚了,也就基本明白桥接的含义了。

一个一个来,先看看什么是桥接?所谓桥接,通俗点说就是在不同的东西之间搭一个桥,让它们能够连接起来,可以相互通讯和使用。那么在桥接模式中到底是给什么东西来搭桥呢?就是为被分离了的抽象部分和实现部分来搭桥,比如前面示例中在抽象的消息和具体消息发送之间搭个桥。

 

第25章访问者模式(Visitor)

访问者模式能给一系列对象透明地添加新功能,从而避免在维护期间对这一系列对象进行修改,而且还能变相实现复用访问者所具有的功能。

由于是针对一系列对象的操作,这也导致,如果只想给一系列对象中的部分对象添加功能,就会有些麻烦;而且要始终能保证把这一系列对象都调用到,不管是循环,还是递归,总之要让每个对象都要被访问到。

 

这份【研磨23种设计模式】共有802页,需要完整版的朋友,可以转发此文关注小编👇👇👇

还有6.17G 23种设计模式视频配合文档来学习,希望大家能够喜欢!!

 

 

学好23种设计模式,走遍天下都不怕!!小编只能够帮助大家到这里了,希望大家能够珍惜这个学习机会!!