设计模式基础学习总结

这篇总结主要是基于我之前设计模式基础系列文章而形成的的。主要是把重要的知识点用自己的话说了一遍,可能会有一些错误,还望见谅和指点。谢谢

更多详细内容可以查看我的专栏文章:设计模式学习
https://blog.csdn.net/a724888/article/category/6780980

设计模式

创建型模式

创建型模式
创建型模式的作用就是创建对象,说到创建一个对象,最熟悉的就是 new 一个对象,然后 set 相关属性。但是,在很多场景下,我们需要给客户端提供更加友好的创建对象的方式,尤其是那种我们定义了类,但是需要提供给其他开发者用的时候。

单例

单例模式保证全局的单例类只有一个实例,这样的话使用的时候直接获取即可,比如数据库的一个连接,Spring里的bean,都可以是单例的。

单例模式一般有5种写法。

第一种是饿汉模式,先把单例进行实例化,获取的时候通过静态方法直接获取即可。缺点是类加载后就完成了类的实例化,浪费部分空间。

第二种是饱汉模式,先把单例置为null,然后通过静态方法获取单例时再进行实例化,但是可能有多线程同时进行实例化,会出现并发问题。

第三种是逐步改进的方法,一开始可以用synchronized关键字进行同步,但是开销太大,而后改成使用volatile修饰单例,然后通过一次检查判断单例是否已初始化,如果未初始化就使用synchronized代码块,再次检查单例防止在这期间被初始化,而后才真正进行初始化。

第四种是使用静态内部类来实现,静态内部类只在被使用的时候才进行初始化,所以在内部类中进行单例的实例化,只有用到的时候才会运行实例化代码。然后外部类再通过静态方法返回静态内部类的单例即可。

第五种是枚举类,枚举类的底层实现其实也是内部类。枚举类确保每个类对象在全局是唯一的。所以保证它是单例,这个方法是最简单的。

工厂模式

简单工厂一般是用一个工厂创建多个类的实例。

工厂模式一般是指一个工厂服务一个接口,为这个接口的实现类进行实例化

抽象工厂模式是指一个工厂服务于一个产品族,一个产品族可能包含多个接口,接口又会包含多个实现类,通过一个工厂就可以把这些绑定在一起,非常方便。

原型模式

一般通过一个实例进行克隆从而获得更多同一原型的实例。使用实例的clone方法即可完成。

建造者模式

建造者模式中有一个概念叫做链式调用,链式调用为一个类的实例化提供便利,一般提供系列的方法进行实例化,实际上就是将set方法改造一下,将原本返回为空的set方法改为返回this实例,从而实现链式调用。

建造者模式在此基础上加入了builder方法,提供给外部进行调用,同样使用链式调用来完成参数注入。

结构型模式

结构型模式
前面创建型模式介绍了创建对象的一些设计模式,这节介绍的结构型模式旨在通过改变代码结构来达到解耦的目的,使得我们的代码容易维护和扩展。

桥接模式

有点复杂。建议参考原文

适配器模式

适配器模式用于将两个不同的类进行适配。

适配器模式和代理模式的异同

比较这两种模式,其实是比较对象适配器模式和代理模式,在代码结构上,
它们很相似,都需要一个具体的实现类的实例。
但是它们的目的不一样,代理模式做的是增强原方法的活;
适配器做的是适配的活,为的是提供“把鸡包装成鸭,然后当做鸭来使用”,
而鸡和鸭它们之间原本没有继承关系。

适配器模式可以分为类适配器,对象适配器等。

类适配器通过继承父类就可以把自己适配成父类了。
而对象适配器则需要把对象传入另一个对象的构造方法中,以便进行包装。

享元模式

/ 享元模式的核心在于享元工厂类,
// 享元工厂类的作用在于提供一个用于存储享元对象的享元池,
// 用户需要对象时,首先从享元池中获取,
// 如果享元池中不存在,则创建一个新的享元对象返回给用户,
// 在享元池中保存该新增对象。

//享元模式
// 英文是 Flyweight Pattern,不知道是谁最先翻译的这个词,感觉这翻译真的不好理解,我们试着强行关联起来吧。Flyweight 是轻量级的意思,享元分开来说就是 共享 元器件,也就是复用已经生成的对象,这种做法当然也就是轻量级的了。
//
// 复用对象最简单的方式是,用一个 HashMap 来存放每次新生成的对象。每次需要一个对象的时候,先到 HashMap 中看看有没有,如果没有,再生成新的对象,然后将这个对象放入 HashMap 中。
//
// 这种简单的代码我就不演示了。

代理模式

// 我们发现没有,代理模式说白了就是做 “方法包装” 或做 “方法增强”。
// 在面向切面编程中,算了还是不要吹捧这个名词了,在 AOP 中,
// 其实就是动态代理的过程。比如 Spring 中,
// 我们自己不定义代理类,但是 Spring 会帮我们动态来定义代理,
// 然后把我们定义在 @Before、@After、@Around 中的代码逻辑动态添加到代理中。

外观模式

外观模式一般封装具体的实现细节,为用户提供一个更加简单的接口。

通过一个方法调用就可以获取需要的内容。

组合模式

//组合模式用于表示具有层次结构的数据,使得我们对单个对象和组合对象的访问具有一致性。

//直接看一个例子吧,每个员工都有姓名、部门、薪水这些属性,
// 同时还有下属员工集合(虽然可能集合为空),
// 而下属员工和自己的结构是一样的,
// 也有姓名、部门这些属性,
// 同时也有他们的下属员工集合。

class Employee {
private String name;
private String dept;
private int salary;
private List<Employee> subordinates; // 下属
}

装饰者模式

装饰者

装饰者模式把每个增强类都继承最高级父类。然后需要功能增强时把类实例传入增强类即可,然后增强类在使用时就可以增强原有类的功能了。

和代理模式不同的是,装饰者模式每个装饰类都继承父类,并且可以进行多级封装。

行为型模式

行为型模式
行为型模式关注的是各个类之间的相互作用,将职责划分清楚,使得我们的代码更加地清晰。

策略模式

策略模式一般把一个策略作为一个类,并且在需要指定策略的时候传入实例,于是我们可以在需要使用算法的地方传入指定算法。

命令模式

命令模式一般分为命令发起者,命令以及命令接受者三个角色。

命令发起者在使用时需要注入命令实例。然后执行命令调用。

命令调用实际上会调用命令接收者的方法进行实际调用。

比如遥控器按钮相当于一条命令,点击按钮时命令运行,自动调用电视机提供的方法即可。

模板方法模式

模板方法一般指提供了一个方法模板,并且其中有部分实现类和部分抽象类,并且规定了执行顺序。

实现类是模板提供好的方法。而抽象类则需要用户自行实现。

模板方法规定了一个模板中方法的执行顺序,非常适合一些开发框架,于是模板方法也广泛运用在开源框架中。

状态模式

少见。

观察者模式和事件监听机制

观察者模式一般用于订阅者和消息发布者之间的数据订阅。

一般分为观察者和主题,观察者订阅主题,把实例注册到主题维护的观察者列表上。

而主题更新数据时自动把数据推给观察者或者通知观察者数据已经更新。

但是由于这样的方式消息推送耦合关系比较紧。并且很难在不打开数据的情况下知道数据类型是什么。

知道后来为了使数据格式更加灵活,使用了事件和事件监听器的模式,事件包装的事件类型和事件数据,从主题和观察者中解耦。

主题当事件发生时,触发该事件的所有监听器,把该事件通过监听器列表发给每个监听器,监听得到事件以后,首先根据自己支持处理的事件类型中找到对应的事件处理器,再用处理器处理对应事件。

责任链模式

责任链通常需要先建立一个单向链表,然后调用方只需要调用头部节点就可以了,后面会自动流转下去。比如流程审批就是一个很好的例子,只要终端用户提交申请,根据申请的内容信息,自动建立一条责任链,然后就可以开始流转了。

更多内容请关注微信公众号【Java技术江湖】

这是一位阿里 Java 工程师的技术小站,作者黄小斜,专注 Java 相关技术:SSM、SpringBoot、MySQL、分布式、中间件、集群、Linux、网络、多线程,偶尔讲点Docker、ELK,同时也分享技术干货和学习经验,致力于Java全栈开发!(关注公众号后回复”资料“即可领取 3T 免费技术学习资源以及我我原创的程序员校招指南、Java学习指南等资源)

Java设计模式学习总结的更多相关文章

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

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

  2. Java设计模式学习记录-模板方法模式

    前言 模板方法模式,定义一个操作中算法的骨架,而将一些步骤延迟到子类中.使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤. 模板方法模式 概念介绍 模板方法模式,其实是很好理解的,具体 ...

  3. Java设计模式学习记录-状态模式

    前言 状态模式是一种行为模式,用于解决系统中复杂的对象状态转换以及各个状态下的封装等问题.状态模式是将一个对象的状态从该对象中分离出来,封装到专门的状态类中,使得对象的状态可以灵活多变.这样在客户端使 ...

  4. Java设计模式学习记录-观察者模式

    前言 观察者模式也是对象行为模式的一种,又叫做发表-订阅(Publish/Subscribe)模式.模型-视图(Model/View)模式. 咱们目前用的最多的就是各种MQ(Message Queue ...

  5. Java设计模式学习记录-备忘录模式

    前言 这次要介绍的是备忘录模式,也是行为模式的一种 .现在人们的智能手机上都会有备忘录这样一个功能,大家也都会用,就是为了记住某件事情,防止以后自己忘记了.那么备忘录模式又是什么样子的呢?是不是和手机 ...

  6. Java设计模式学习记录-迭代器模式

    前言 这次要介绍的是迭代器模式,也是一种行为模式.我现在觉得写博客有点应付了,前阵子一天一篇,感觉这样其实有点没理解透彻就写下来了,而且写完后自己也没有多看几遍,上次在面试的时候被问到java中的I/ ...

  7. Java设计模式学习记录-解释器模式

    前言 这次介绍另一个行为模式,解释器模式,都说解释器模式用的少,其实只是我们在日常的开发中用的少,但是一些开源框架中还是能见到它的影子,例如:spring的spEL表达式在解析时就用到了解释器模式,以 ...

  8. Java设计模式学习记录-命令模式

    前言 这次要介绍的是命令模式,这也是一种行为型模式.最近反正没有面试机会我就写博客呗,该投的简历都投了.然后就继续看书,其实看书也会给自己带来成就感,原来以前不明白的东西,书上已经给彻底的介绍清楚了, ...

  9. Java设计模式学习记录-享元模式

    前言 享元模式也是一种结构型模式,这篇是介绍结构型模式的最后一篇了(因为代理模式很早之前就已经写过了).享元模式采用一个共享来避免大量拥有相同内容对象的开销.这种开销最常见.最直观的就是内存损耗. 享 ...

  10. Java设计模式学习记录-外观模式

    前言 这次要介绍的是外观模式(也称为门面模式),外观模式也属于结构型模式,其实外观模式还是非常好理解的,简单的来讲就是将多个复杂的业务封装成一个方法,在调用此方法时可以不必关系具体执行了哪些业务,而只 ...

随机推荐

  1. SpringCloud使用Sofa-lookout监控(基于Eureka)

    本文介绍SpringCloud使用Sofa-lookout,基于Eureka服务发现. 1.前景 本文属于是前几篇文章的后续,其实一开始感觉这个没有什么必要写的,但是最近一个朋友问我关于这个的问题,所 ...

  2. Shell脚本学习 - 运算符

    继续shell脚本学习.上一篇是基本数据类型和语法的总结,这一篇是运算相关的操作. 运算符 bash不支持简单的数学计算,需要依赖其他命令实现. expr可以代为实现. # 表达式一般这么写 ` + ...

  3. java简单框架设计

    设计框架包可以作为一个工具给大家用,需要有完全不同设计思路给出来,不同于我们去做一个web服务.网站. 或者一个业务微服务,需要从原来使用视角转换成一个构建者视角. 框架或者工具,更多是框架来管理或者 ...

  4. DCDC设计指南二

    DCDC电源设计指导:二 这一讲以一款SOP-8封装的Synchronous Step-Down Converter(同步降压转换器)电源IC为例,讲下电源的PCB设计. 如第一讲中所说,开始设计时就 ...

  5. JAVA基础复习与总结<五> String类_File类_Date类

    String类 .Java字符串就是Unicode字符序列,例如串“Java”就是4个Unicoe字符组成. .Java没有内置的字符串类型,而是在标准java类库中提供了一个预定义的类String, ...

  6. #工具 Intellij IDEA中自定义的Maven Archetype管理

    背景,手贱在输入自定义的 archetype时后面多输入了一个空格 解决:自定义的Archetype 会保存在Windows下面的文件中 C:\Users\<user>\.IntelliJ ...

  7. NOIP2012提高组day2 T2借教室

    这题骗分可以骗到满分(可能是数据不太强给强行过去了) 这道题如果是按照题意去模拟用循环去修改区间的话只有45分,正解是二分+差分数组,骗分也是差分数组但是没有使用二分,时间复杂度在最坏的情况下是O(n ...

  8. c#坐标系互相转换

    转自群友的博客:https://www.xiaofengyu.com/?p=108 群友的github地址:https://github.com/jfwangncs/GPSConvert  各种坐标系 ...

  9. PeopleSoft 启用多语言输入

    今天,我的一位同事询问有的人有语言选择,有的人没有(如下图所示). 以下是PT856.09菜单路经: 主菜单-->我的首选项--->一般设置--->多语言条目

  10. 读取 ini 配置文件

    ini 配置文件格式:db_config.ini '''[section]option=value''' [DATABASE1] host=192.168.30.80 port= user=testa ...