一、概述

  思维导图

    

  GoF(“四人帮”,又称Gang of Four,即Erich Gamma, Richard Helm, Ralph Johnson & John Vlissides)

1.1、设计模式遵循的原则有6个

1、开闭原则(Open Close Principle)

  对扩展开放,对修改关闭

2、里氏代换原则(Liskov Substitution Principle)

  只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。

3、依赖倒转原则(Dependence Inversion Principle)

  这个是开闭原则的基础,对接口编程,依赖于抽象而不依赖于具体。

4、接口隔离原则(Interface Segregation Principle)

  使用多个隔离的借口来降低耦合度。

5、迪米特法则(最少知道原则)(Demeter Principle)

  一个实体应当尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立。

6、合成复用原则(Composite Reuse Principle)

  原则是尽量使用合成/聚合的方式,而不是使用继承。继承实际上破坏了类的封装性,超类的方法可能会被子类修改。

1.2、设计模式分类与简介

创建型模式(5个):单例模式、原型模式、建造者模式、工厂模式、抽象工厂模式。

结构型模式(7个):桥接模式、外观模式、组合模式、装饰模式、适配器模式、代理模式、享元模式。

行为型模式(11个):迭代器模式、解释器模式、观察者模式、中介者模式、访问者模式、备忘录模式、状态模式、策略模式、模版方法模、命令模式、职责链模式式。

类别表格

类型 序号 设计模式 类关系 定义 使用场景 使用实例   相关设计模式
创建型模式 0 简单工厂(Sample Factory)          
1 工厂方法模式(Factory Method)  

定义一个用于创建对象的接口,让子类决定将哪一个类实例化。

使一个类的实例化延迟到其子类

1、创建对象需要大量重复的代码
2、应用层不依赖于产品类实例如何被创建、实现等细节
3、一个类通过其子类来指定创建那个对象

   
2 抽象工厂模式(Abstract Factory)   提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类

1、客户端(应用层)不依赖于具体产品类实例如何被创建、实现等细节
2、强调一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量重复的代码
3、提供一个产品类的库,所有的产品以同样的接口出现从而使客户端不依赖于具体实现

java.sql.Connection
java.sql.Statement
sqlsessionfactory

 
3 单例模式(Singleton)   保证一个类仅有一个实例,并提供一个访问它的全局访问点 

1、在多个线程之间,比如servlet环境,共享同一个资源或者操作同一个对象。
2、在整个程序空间使用全局变量,共享资源。
3、在大规模系统中,为了性能的考虑,需要节省对象的创建时间等等。
想确保任何情况下都绝对只有一个实例

jdk Runtime 饿汉式
spring AbstractFactoryBean 懒汉式
spring 创建bean 单例注册表

 
4 建造者模式(Builder)   将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。 1、如果一个对象有非常复杂的内部结构,在用户不知道对象的
建造过程和细节的情况下就可以直接创建复杂的对象。
2、想把复杂对象的创建和使用分离。

jdk StringBuilder、StringBuffer
spring UriComponents和UriComponentsBuilder
BeanDefinitionBuilder
mybatis中的SqlSessionFactoryBuilder

 
5 原型模式(Prototype)   用原型实例指定创建对象的种类,并且通过拷贝这个原型来创建新的对象。    ArrayList的clone()
HashMap的clone()
CacheKey的clone()
 
             
结构型模式 1 适配器模式(Adapter)  

将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口

不兼容而不能一起工作的那些类可以一起工作。

已经存在的类,它的方法和需求不匹配时(方法结果相同或相似)
不是软件设计阶段考虑的设计模式,是随着软件维护。
由于不同产品、不同厂家造成功能类似而接口不相同情况下的解决方案

jdk XmlAdapter
spring AdvisorAdapter、MethodBeforeAdviceAdapter
JpaVendorAdapter
HandlerAdapter、DispatcherServlet、Controller

适配器复用现有的接口,

外观模式则是定义新的接口

2 装饰器模式(Decorator)   动态地给一个对象添加一些额外的职责。就扩展功能而言, 它比生成子类方式更为灵活。

扩展一个类的功能或给一个类添加附加职责
动态的给一个对象添加功能,这些功能可以再动态的撤销
当不能采用生成子类的方法进行扩充时。

Java Reader\InputStream
spring TransactionAwareCacheDecorator
mybatis org.apache.ibatis.cache.Cache

 
3 代理模式(Proxy)   为其他对象提供一个代理以控制对这个对象的访问。  保护目标对象、增强目标对象

jdk java.lang.reflect.proxy
spring ProxyFactoryBean
mybatis MapperProxy

 
4 外观模式(Facade)  

为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,
这个接口使得这一子系统更加容易使用。

子系统越来越复杂,增加外观模式是供简单调用接口
构建多层系统结构,利用外观对象作为每层的入口,简化层间调用

spring JdbcUtils
mybatis Configuration
apache RequestFacade

1、外观模式:关注外界和子系统之间的交互
2、中介者模式:关注子系统内部之间的交互
3、通常把外观模式中的外观对象做成单例模式
4、外观模式可以通过抽象工厂获得子系统的实例,
这样子系统内部可以对外观类进行屏蔽。

5 桥接模式(Bridge)   将抽象部分与它的实现部分分离,使它们都可以独立地变化。

1、如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,
避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。
2、抽象化角色和实现化角色可以以继承的方式独立扩展而互不影响,在程序运
行时可以动态将一个抽象化子类的对象和一个实现化子类的对象进行组合,即系统需要对、抽象化角色和实现化角色进行动态耦合。
3、一个类存在两个(或多个)独立变化的维度。且这两个(或多个)维度都需要独立进行扩展
4、虽然在系统中使用继承是没有问题的,但是由于抽象化角色和具体化角色需要独立变化,
设计要求需要独立管理这两者。
5、不希望使用继承,或因为多层继承导致系统类的个数剧增

jdk sql.Driver、
DriverManager与DriverInfo

 
6 组合模式(Composite)  

将对象组合成树形结构以表示“部分-整体”的层次结构。

它使得客户对单个对象和复合对象的使用具有一致性。

希望客户端可以忽略组合对象与单个对象的差异时
处理一个树形结构时

java.awt.Container、Component
java.util.HashMap、
ArrayList、List、Collection

 
7 享元模式(Flyweight)   运用共享技术有效地支持大量细粒度的对象。

常常应用于系统底层的开发,以便解决系统的性能问题。
系统有大量相似对象、需要缓冲池的场景。

比如:String常量池、Integer常量池、
数据库连接池、线程池
jdk Integer→valueOf IntegerCache
tomcat GenericObjectPoolConfig
apache GenericKeyedObjectPool

 
             
行为型模式 1 策略模式(Strategy) 父子类之间

定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。

本模式使得算法的变化可独立于使用它的客户。

多个类只区别在表现行为不同,可以使用Strategy模式,在运行时动态选择具体要执行的行为。
需要在不同情况下使用不同的策略(算法),或者策略还可能在未来用其它方式来实现。
在有多种算法相似的情况下,使用 if...else 所带来的复杂和难以维护。
对客户隐藏具体策略(算法)的实现细节,彼此完全独立。

java.util.Comparator
java.util.TreeMap
spring Resource

 
2 模板方法模式(Template Method) 父子类之间

定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。

Template Method 使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

1、具有统一的操作步骤或操作过程
2、具有不同的操作细节
3、存在多个具有同样操作步骤的应用场景,
但某些具体的操作细节却各不相同

jdk:AbstractList
servlet:HttpServlet
mybatis:BaseExecutor

 
3 观察者模式(Observer) 类与类之间

定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,

所有依赖于它的对象都得到通知并自动刷新。

一个对象状态改变给其他对象通知的问题,
而且要考虑到易用和低耦合,保证高度的协作。
关联行为场景,建立一套触发机制

spring RequestContextListener、
ServletRequestListener、
EventListener、ReaderEventListener
google Guava之EventBus

 
4 迭代器模式(Iterator) 类与类之间 提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。

1、访问一个聚合对象的内容而无须暴露它的内部表示。
2、需要为聚合对象提供多种遍历方式。
3、为遍历不同的聚合结构提供一个统一的接口。

 jdk Iterator、ArrayList中的Itr  
5

责任链模式

(Chain of Responsibility)

类与类之间 

为解除请求的发送者和接收者之间耦合,而使多个对象都有机会处理这个请求。

将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它。

一个请求的处理需要多个对象当中的一个或几个协作处理
1、有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。
2、在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
3、可动态指定一组对象处理请求。

struts的拦截器、servlet的过滤器、
Dubbo中的Filter、Mybatis中的Plugin
javax.servlet.Filter的doFilter、FilterChain
Spring Security

 
6 命令模式(Command) 类与类之间 

将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;

对请求排队或记录请求日志,以及支持可取消的操作。

认为是命令的地方都可以使用命令模式
请求调用者和请求接收者需要解耦,使得调用者和接收者不直接交互
需要抽象出等待执行的行为

Runnable实现Runnable接口是具体的命令
junit.Test的run方法就是execute方法

 
7 备忘录模式(Memento) 类的状态

在不破坏封装性的前提下,捕获一个对象的内部状态,

并在该对象之外保存这个状态。这样以后就可将该对象恢复到保存的状态。

需要保存/恢复数据的相关状态场景
提供一个可回滚的操作。

spring StateManageableMessageContext  
8 状态模式(State) 类的状态

允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它所属的类。

1、行为随状态改变而改变的场景。
2、条件、分支语句的代替者。

javax.faces.lifecycle.Lifecycle
javax.faces.webapp.FacesServlet

 
9 访问者模式(Visitor) 通过中间类

表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素

的类的前提下定义作用于这些元素的新操作。

1、对象结构中对象对应的类很少改变,但经常需要在此对象结构上定义新的操作。
2、需要对一个对象结构中的对象进行很多不同的并且不相关的操作,
而需要避免让这些操作"污染"这些对象的类,也不希望在增加新操作时修改这些类。

jdk FileVisitor、SimpleFileVisitor
spring BeanDefinitionVisitor

 
10 中介者模式(Mediator) 通过中间类 

用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,

从而使其耦合松散,而且可以独立地改变它们之间的交互。

1、系统中对象之间存在比较复杂的引用关系,
导致它们之间的依赖关系结构混乱而且难以复用该对象。
2、想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。

java.util.Timer就是一个中介者,
TimerTask就是user(同事类),
通过sched进行协调

 
11 解释器模式(Interpreter) 通过中间类

给定一个语言, 定义它的文法的一种表示,并定义一个解释器,

该解释器使用该表示来解释语言中的句子。

1、可以将一个需要解释执行的语言中的句子表示为一个抽象语法树。
2、一些重复出现的问题可以用一种简单的语言来进行表达。
3、一个简单语法需要解释的场景。

java.util.regex.Pattern正则解释器
Spring SpelExpressionParser
expression4J

 

1.2.1、创建型模式

1.2.2、结构型模式

  其中对象的适配器模式是各种模式的起源

  

1.2.3、行为型模式

主要作用于类间作用

  

1.3、设计模式的结构图

  

001-java 设计模式概述的更多相关文章

  1. java设计模式概述

    java的设计模式大体上分为三大类: 创建型模式(5种):工厂方法模式,抽象工厂模式,单例模式,建造者模式,原型模式. 结构型模式(7种):适配器模式,装饰器模式,代理模式,外观模式,桥接模式,组合模 ...

  2. 【java】 java 设计模式概述

    一.设计模式的分类 总体来说设计模式分为三大类: 创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥接 ...

  3. java 28 - 1 设计模式 之 面向对象思想设计原则和模版设计模式概述

    在之前的java 23 中,了解过设计模式的单例模式和工厂模式.在这里,介绍下设计模式 面向对象思想设计原则 在实际的开发中,我们要想更深入的了解面向对象思想,就必须熟悉前人总结过的面向对象的思想的设 ...

  4. Java设计模式学习笔记(一) 设计模式概述

    前言 大约在一年前学习过一段时间的设计模式,但是当时自己的学习方式比较低效,也没有深刻的去理解.运用所学的知识. 所以现在准备系统的再重新学习一遍,写一个关于设计模式的系列博客. 废话不多说,正文开始 ...

  5. Java设计模式(一):设计模式概述、UML图、设计原则

    1 设计模式概述 1.1 软件设计模式的产生背景 "设计模式"最初并不是出现在软件设计中,而是被用于建筑领域的设计中. 1977年美国著名建筑大师.加利福尼亚大学伯克利分校环境结构 ...

  6. Java设计模式学习资源汇总

    本文记录了Java设计模式学习书籍.教程资源.此分享会持续更新: 1. 设计模式书籍 在豆瓣上搜索了一把,发现设计模式贯穿了人类生活的方方面面.还是回到Java与程序设计来吧. 打算先归类,再浏览,从 ...

  7. java设计模式综合项目实战视频教程

    java设计模式综合项目实战视频教程 视频课程目录如下: 第01节课:本课程整体内容介绍:X-gen系统概况,包括:引入.X-gen项目背景.X-gen的HelloWorld第02节课:X-gen整体 ...

  8. Java设计模式系列-抽象工厂模式

    原创文章,转载请标注出处:https://www.cnblogs.com/V1haoge/p/10755412.html 一.概述 抽象工厂模式是对工厂方法模式的再升级,但是二者面对的场景稍显差别. ...

  9. Java设计模式系列-工厂方法模式

    原创文章,转载请标注出处:<Java设计模式系列-工厂方法模式> 一.概述 工厂,就是生产产品的地方. 在Java设计模式中使用工厂的概念,那就是生成对象的地方了. 本来直接就能创建的对象 ...

  10. Java设计模式系列-装饰器模式

    原创文章,转载请标注出处:<Java设计模式系列-装饰器模式> 一.概述 装饰器模式作用是针对目标方法进行增强,提供新的功能或者额外的功能. 不同于适配器模式和桥接模式,装饰器模式涉及的是 ...

随机推荐

  1. java基础(3)---Scanner键盘输入

    1.使用scanner类: import java.util.Scanner; class ScannerTest{ public static void main( String[] args){ ...

  2. jcmd命令实战

    继续来根据之前的那篇infoq的文章的介绍熟悉工具,上一次咱们学习使用了: 接下来学习它里面提到的另一个工具: jcmd是一个非常之强大的命令行工具,能输出很多很多的信息,也是在处理JVM的一些问题经 ...

  3. SQL SERVER中如何查找存储过程中一段代码

    select b.name ,a.text from syscomments a,sysobjects b where and object_id(b.name)=a.id and b.xtype i ...

  4. NodeJS开发博客(二) 接入数据库

    1. mysql 数据库下载网址:https://dev.mysql.com/downloads/mysql/ 账号是 root 密码是 a1************ 网站账号是邮箱,密码是 Aa1* ...

  5. php版网站站打包程序【配合webshell】(原创)

    因为大马只能下载一些单文件,无法下载文件夹里的文件,所以花费一些时间写了一个PHP脚本,打包全站数据,在此分享!切勿做违法事情! 使用方法: 1.将该程序上传到网站的目录下,如/zip.php : 2 ...

  6. Codeforces Round #413 (Div1 + Div. 2) C. Fountains(树状数组维护最大值)

    题目链接:https://codeforces.com/problemset/problem/799/C 题意:有 c 块硬币和 d 块钻石,每种喷泉消耗硬币或钻石中的一种,每个喷泉有一个美丽值,问建 ...

  7. BZOJ 3636 教义问答手册 (分治)

    题意 一个整数数列,多次询问某段区间[li,ri][l_i,r_i][li​,ri​]内,选出若干个长度为LLL且不相交的连续段使选出来的数和最大. 分析 首先想朴素的区间DPDPDP 设f[i][j ...

  8. DOM事件监听和触发

    EventTargetAPI定义了DOM事件(mouse事件等)的监听和触发方法,所有的DOM节点都部署了这个接口. 这个接口有三个方法:addEventListener, removeEventLi ...

  9. HDU4254 A Famous Game

    luogu嘟嘟嘟 这题刚开始特别容易理解错:直接枚举所有\(n + 1\)种情况,然后算哪一种情况合法,再统计答案. 上述思想的问题就在于我们从已知的结果出发,默认这种每一种情况中取出\(q\)个红球 ...

  10. About & Ideas & Queries

    About Blog主现高一,文化课和OI啥都不会 本Blog主太懒,所以很多内容都缩在一个文章里,如数学.图论大礼包 https://wenku.baidu.com/view/56d76029647 ...