【零】Java设计模式GOF23之总结

2024-01-29 13:50
文章标签 java 总结 设计模式 gof23

本文主要是介绍【零】Java设计模式GOF23之总结,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

设计模式主要有3个大分类

创建型模式:用来建造对象

一、单例模式:

保证一个类只有一个实例,并且提供一个访问该实例的全局访问点。

常见应用场景

1.全局计数器采用单例模式,不然不好同步。

2.应用程序的日志应用,共享日志文件一直处于打开状态,所以只能有一个实例去操作,否则内容不好追加。

3.数据库连接池的设计也用单例,否则浪费资源。

4.spring中的bean默认都是单例。

5.servlet是单例。

6.spring mvc/ structs1,控制器对象是单例。

7.项目中工具类,一般都用单例,没必要浪费资源。

常见实现方式

1.饿汉模式(线程安全、调用效率高、不能延时加载)

2.懒汉模式(线程安全、调用效率不高(getInstance方法用了synchronized同步方法)、可以延时加载)

3.静态内部类模式(线程安全、调用率高、可以延时加载)

4.双重同步锁单例模式

5.枚举单例(线程安全、调用率高、不能延时加载、不会被反射反序列化生成多个实例

代码

各种单例模式代码演示

UML图

二、工厂模式

选择实现类、创建对象统一管理和控制。

实现了创建者和调用者的分离

用工厂方法代替new操作。

常见应用场景

1.JDK中Calendar的getInstance方法

2.JDBC中Connection对象的获取

3.Hibernate中SessionFactory创建session对象

4.spring中IOC容器创建管理bean对象

5.反射中Class对象的newInstance

6.JDK中java.util.concurrent包中的Executors类,就是一个静态工厂,用来创建各种线程池。代码示例用这个案例

1.简单工厂模式

用来生产同一等级结构中的任意产品。(对于增加新的产品,需要修改已有代码

代码

【十】Java设计模式GOF23之简单工厂模式(静态工厂模式)

UML图

源码中间多了一层抽象AbstractExecutorService,在普通的静态工厂中是不需要这层抽象的。

2.工厂方法模式

用来生产同一等级结构中的固定产品。(支持增加任意产品)

代码

【十一】Java设计模式GOF23之工厂方法模式

UML图

3.抽象工厂模式

用来生产不同产品族的全部产品。(对于增加新的单个产品,无能为力,支持增加产品族)

它是工厂方法模式的升级版,在有多个业务品种、业务分类时,通过抽象工厂模式产生需要的对象是一种非常好的解决方式。

代码

【十二】Java设计模式GOF23之抽象工厂模式

UML图

三、建造者模式

分离了对象子组件的单独构造(有builder来负责)和装配(由Director负责)。从而可以构造出复杂的对象。

这个模式适用于:某个对象的构建过程复杂的情况下。

由于实现了构建和装配的解耦。不同的构建器,相同的装配,也可以做出不同的对象;相同的构建器,不同的装配顺序也可以做出不同的对象。

也就是实现了构建算法、装配算法的解耦,实现了更好的复用。

关键代码:建造者:创建和提供实例,导演:管理建造出来的实例的依赖关系。

常见应用场景

1.SpringBuilder类的append方法

2.SQL中的PreparedStatement

3.JDOM中的DomBuilder、SAXBuilder

4.去肯德基,汉堡、可乐、薯条、炸鸡翅等是不变的,而其组合是经常变化的,生成出所谓的"套餐"。

之前遇到一个笔试题应该就是考构建者模式的,例子是说的星巴克。“咖啡价格问题:星巴克咖啡有基本的美式,摩卡,拿铁三种,价格都不一样。同时有很多的配料,包括香草、肉桂、奶油、焦糖、巧克力,每种配料的价格也不一样。一种咖啡可以选多种配料。以OOD的方式来计算每杯咖啡的价格。”

代码

【五】Java设计模式GOF23之建造者模式

UML图

四、原型模式prototype

如果通过new创建一个对象需要非常繁琐的数据准备和访问权限,则可以用原型模式。

就是java中的克隆,以某个对象为原型,复制出新对象。新对象具备原型对象的特点。

优势:效率高(直接克隆,避免了重新执行构造过程步骤)

代码

【十四】Java设计模式GOF23之原型模式

结构型模式:

一、适配器模式

将一个类的接口转换成客户希望的另外一个接口。

适配器不是在详细设计时添加的,而是解决正在服役的项目的问题。一个系统如果太多出现这种情况,无异于一场灾难。

类适配器用继承实现

对象适配器用依赖实现

代码

【十】Java设计模式GOF23之适配器模式(类方式实现、对象方式实现)

个人思考:这个设计模式不是很鸡肋吗,还是我没理解到它的精髓?

直接用adaptee去实现target接口,在request方法中写自己的specificRequest方法的逻辑就好了啊,为毛要多个adapter类出来?

什么毛病?

UML图

二、桥接模式

它的主要特点是把抽象(abstraction)与行为实现(implementation)分离开来,从而可以保持各部分的独立性以及应对它们的功能扩展

适用处理多维度变化。

举个例子,引用例子Java 设计模式之桥接模式(七)

 

这个例子里面,电脑类型是一个维度,电脑品牌是一个维度,把品牌放在类型下面,那么类型的增加会导致品牌的增加。

品牌的增加,也会去每个类型下面增加一个对象。

桥接模式的意思就是,以上面这个例子来说,应该提两个维度的接口或父类出来,他们之间可以考虑依赖的方式。这样一个维度变更不影响另外一个维度。比如:

三、装饰模式

四、组合模式

五、外观模式

六、享元模式

七、代理模式

核心作用:通过代理,控制对对象的访问

可以详细控制访问某个(某类)对象的方法,在调用这个方法前做前置处理,调用这个方法后做后置处理。(Spring AOP的围观实现)。从而实现将统一流程代码放到代理类中处理。

应用场景

1.安全代理:屏蔽对真实角色的直接访问

2.远程代理:通过代理类处理远程方法调用RMI

3.延迟加载:先加载轻量级的代理对象,真正需要时再加载真实对象

1.静态代理

自己定义代理类

代码

【十五】Java设计模式GOF23之静态代理

UML图

2.动态代理

动态生成代理类

代码

这里使用反射来实现的

【十六】Java设计模式GOF23之动态代理

UML图

行为型模式:

一、模板方法模式

java.util.AbstractQueuedSynchronizer类的设计就使用了模板方法模式。

代码

父类AQS,写了释放锁的逻辑release()方法,

而release()方法中有部分逻辑是需要调用tryRelease()方法实现:

    public final boolean release(int arg) {if (tryRelease(arg)) {Node h = head;if (h != null && h.waitStatus != 0)unparkSuccessor(h);return true;}return false;}

父类AQS并没有实现tryRelease()方法,而是由子类Sync去实现自己的tryRelease()方法。

父类描述了整体的释放锁的逻辑,部分细节由子类描述,不同的子类有不同的描述。

比如ReentrantLock中的Sync的tryRelease()

protected final boolean tryRelease(int releases) {int c = getState() - releases;if (Thread.currentThread() != getExclusiveOwnerThread())throw new IllegalMonitorStateException();boolean free = false;if (c == 0) {free = true;setExclusiveOwnerThread(null);}setState(c);return free;}

countDownLatch中的Sync的tryRelease()

        protected boolean tryReleaseShared(int releases) {// Decrement count; signal when transition to zerofor (;;) {int c = getState();if (c == 0)return false;int nextc = c-1;if (compareAndSetState(c, nextc))return nextc == 0;}}

【二十一】Java多线程J.U.C之AQS框架源码导读(总结、干货)(模板模式template pattern)

UML图

二、命令模式

命令模式(Command Pattern)是一种数据驱动的设计模式,它属于行为型模式。请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。

JDK的java.util.concurrent包的ThreadPoolExecutor类就用到命令模式。

简易命令模式组成
1.Command(抽象命令类): 声明了用于执行请求的的exceute()等方法

2.ConcreteCommand(具体命令类): 抽象命令类的子类,对应具体的接收者对象,将接收者对象的动作绑定其中。在实现execute()方法时,将调用接收者对象的相关操作(Action)。

3.Invoker(调用者): 调用命令对象执行请求,它持有了一个命令队列,客户端代码可以向它提交要执行的任务(命令)。

4.Receiver(接收者): 真正的命令执行对象。任何一个类都可以成为接收者,实施和执行请求的方法叫做行动方法。
UML图

代码 

【十三】Java设计模式GOF23之命令模式(例子ThreadPoolExecutor类)

三、迭代器模式

简介

迭代器模式(Iterator Pattern)是 Java 和 .Net 编程环境中非常常用的设计模式。这种模式用于顺序访问集合对象的元素,不需要知道集合对象的底层表示。

它提供一种方法顺序访问一个聚合对象中各个元素, 而又无须暴露该对象的内部表示。

主要成员

1.抽象容器:一般是一个接口,提供一个iterator()方法,例如java中的Collection接口,List接口,Set接口等。
2.具体容器:就是抽象容器的具体实现类,比如List接口的有序列表实现ArrayList,List接口的链表实现LinkList,Set接口的哈希列表的实现HashSet等。
3.抽象迭代器:定义遍历元素所需要的方法,一般来说会有这么三个方法:取得第一个元素的方法first(),取得下一个元素的方法next(),判断是否遍历结束的方法isDone()(或者叫hasNext()),移出当前对象的方法remove(),
4.迭代器实现:实现迭代器接口中定义的方法,完成集合的迭代。
UML图

代码

【十四】Java设计模式GOF23之迭代器模式

四、观察者模式

主要用于1:N的通知

应用场景:聊天室。发布/订阅。网络游戏。消息广播。事件监听。

多个订阅者称为观察者。需要同步给多个订阅者的数据封装到对象中,称为目标。

代码

【十七】Java设计模式GOF23之观察者模式

UML图

五、中介者模式

六、备忘录模式

七、解释器模式

八、状态模式

九、策略模式

在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。

在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。

策略模式的角色和职责

1.Strategy:策略(算法)抽象

2.ConcreteStrategy:各种策略(算法)的具体实现

3.Context:策略的外部封装类,或者说策略的容器。根据不同的策略执行不同的行为。策略由外部环境决定。

java.util.concurrent中的ThreadPoolExecutor类在实现拒绝策略的时候就是用的策略模式
代码

【十二】Java设计模式GOF23之策略模式(ThreadPoolExecutor类的拒绝策略源码)

UML图

十、责任链模式

责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。

在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。

javax.servlet.Filter就是用的责任链模式
代码

【十一】Java设计模式GOF23之责任链模式

UML图

十一、访问者模式

这篇关于【零】Java设计模式GOF23之总结的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/657125

相关文章

Spring Security基于数据库的ABAC属性权限模型实战开发教程

《SpringSecurity基于数据库的ABAC属性权限模型实战开发教程》:本文主要介绍SpringSecurity基于数据库的ABAC属性权限模型实战开发教程,本文给大家介绍的非常详细,对大... 目录1. 前言2. 权限决策依据RBACABAC综合对比3. 数据库表结构说明4. 实战开始5. MyBA

Spring Security方法级安全控制@PreAuthorize注解的灵活运用小结

《SpringSecurity方法级安全控制@PreAuthorize注解的灵活运用小结》本文将带着大家讲解@PreAuthorize注解的核心原理、SpEL表达式机制,并通过的示例代码演示如... 目录1. 前言2. @PreAuthorize 注解简介3. @PreAuthorize 核心原理解析拦截与

一文详解JavaScript中的fetch方法

《一文详解JavaScript中的fetch方法》fetch函数是一个用于在JavaScript中执行HTTP请求的现代API,它提供了一种更简洁、更强大的方式来处理网络请求,:本文主要介绍Jav... 目录前言什么是 fetch 方法基本语法简单的 GET 请求示例代码解释发送 POST 请求示例代码解释

Java图片压缩三种高效压缩方案详细解析

《Java图片压缩三种高效压缩方案详细解析》图片压缩通常涉及减少图片的尺寸缩放、调整图片的质量(针对JPEG、PNG等)、使用特定的算法来减少图片的数据量等,:本文主要介绍Java图片压缩三种高效... 目录一、基于OpenCV的智能尺寸压缩技术亮点:适用场景:二、JPEG质量参数压缩关键技术:压缩效果对比

Java调用C++动态库超详细步骤讲解(附源码)

《Java调用C++动态库超详细步骤讲解(附源码)》C语言因其高效和接近硬件的特性,时常会被用在性能要求较高或者需要直接操作硬件的场合,:本文主要介绍Java调用C++动态库的相关资料,文中通过代... 目录一、直接调用C++库第一步:动态库生成(vs2017+qt5.12.10)第二步:Java调用C++

springboot+dubbo实现时间轮算法

《springboot+dubbo实现时间轮算法》时间轮是一种高效利用线程资源进行批量化调度的算法,本文主要介绍了springboot+dubbo实现时间轮算法,文中通过示例代码介绍的非常详细,对大家... 目录前言一、参数说明二、具体实现1、HashedwheelTimer2、createWheel3、n

Java利用docx4j+Freemarker生成word文档

《Java利用docx4j+Freemarker生成word文档》这篇文章主要为大家详细介绍了Java如何利用docx4j+Freemarker生成word文档,文中的示例代码讲解详细,感兴趣的小伙伴... 目录技术方案maven依赖创建模板文件实现代码技术方案Java 1.8 + docx4j + Fr

SpringBoot首笔交易慢问题排查与优化方案

《SpringBoot首笔交易慢问题排查与优化方案》在我们的微服务项目中,遇到这样的问题:应用启动后,第一笔交易响应耗时高达4、5秒,而后续请求均能在毫秒级完成,这不仅触发监控告警,也极大影响了用户体... 目录问题背景排查步骤1. 日志分析2. 性能工具定位优化方案:提前预热各种资源1. Flowable

基于SpringBoot+Mybatis实现Mysql分表

《基于SpringBoot+Mybatis实现Mysql分表》这篇文章主要为大家详细介绍了基于SpringBoot+Mybatis实现Mysql分表的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可... 目录基本思路定义注解创建ThreadLocal创建拦截器业务处理基本思路1.根据创建时间字段按年进

Java编译生成多个.class文件的原理和作用

《Java编译生成多个.class文件的原理和作用》作为一名经验丰富的开发者,在Java项目中执行编译后,可能会发现一个.java源文件有时会产生多个.class文件,从技术实现层面详细剖析这一现象... 目录一、内部类机制与.class文件生成成员内部类(常规内部类)局部内部类(方法内部类)匿名内部类二、