From 0f2e4358ae4e0921f084f4b835cfc28e4978bfff Mon Sep 17 00:00:00 2001 From: xiongraorao Date: Wed, 29 Aug 2018 16:48:52 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=AE=BE=E8=AE=A1=E6=A8=A1?= =?UTF-8?q?=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- interview/java/设计模式.md | 340 +++++++++++++++++++++++++++++++++++++ 1 file changed, 340 insertions(+) diff --git a/interview/java/设计模式.md b/interview/java/设计模式.md index 502f595f..4de998cf 100644 --- a/interview/java/设计模式.md +++ b/interview/java/设计模式.md @@ -1,12 +1,38 @@ - [快速理解设计模式](#快速理解设计模式) +- [UML类图术语](#uml类图术语) + - [类的属性的表示方式](#类的属性的表示方式) + - [类的方法的表示方式](#类的方法的表示方式) + - [类和类之间关系的表示方式](#类和类之间关系的表示方式) - [创建型模式](#创建型模式) - [单例模式](#单例模式) - [简单工厂模式](#简单工厂模式) - [工厂方法](#工厂方法) - [抽象工厂模式](#抽象工厂模式) - [建造者(生成器)模式](#建造者生成器模式) + - [原型模式](#原型模式) +- [行为型模式](#行为型模式) + - [责任链模式](#责任链模式) + - [命令模式](#命令模式) + - [解释器模式](#解释器模式) + - [迭代器模式](#迭代器模式) + - [中介者模式](#中介者模式) + - [备忘录模式](#备忘录模式) + - [观察者模式](#观察者模式) + - [状态模式](#状态模式) + - [策略模式](#策略模式) + - [模板方法](#模板方法) + - [访问者模式](#访问者模式) +- [结构型](#结构型) + - [适配器模式](#适配器模式) + - [桥接模式](#桥接模式) + - [组合模式](#组合模式) + - [装饰者模式](#装饰者模式) + - [外观模式](#外观模式) + - [享元模式](#享元模式) + - [代理模式](#代理模式) +- [参考链接](#参考链接) @@ -14,6 +40,73 @@ 设计模式主要分为3大类,分别是创建型模式、行为型模式和结构型模式。 +# UML类图术语 + +## 类的属性的表示方式 + +![](https://images2015.cnblogs.com/blog/617148/201606/617148-20160612221055090-339746853.jpg) + +· + :表示public + +· - :表示private + +· #:表示protected(friendly也归入这类) + +## 类的方法的表示方式 + +![](https://images2015.cnblogs.com/blog/617148/201606/617148-20160612222105058-2140837213.jpg) + +## 类和类之间关系的表示方式 + +1、依赖关系 + +一个类的某个方法引用到了另外一个类,即一个类的调用依赖于另外一个类的定义。 + +UML表示:采用虚线+箭头的方式表示依赖关系 + +![](https://images2015.cnblogs.com/blog/422101/201609/422101-20160928074646719-2042921908.png) + +2、关联关系 + +体现的是两个类或者类和接口之间语义级别的强依赖关系,它使得一个类知道另外一个类的属性和方法,通常是一个类拥有另外一个类或者接口的成员变量。 + +UML类图:使用普通箭头表示 + +![](https://images2015.cnblogs.com/blog/422101/201609/422101-20160928074707703-1561044397.png) + +3、聚合关系 + +一种**强**的关联关系,聚合是整体和个体之间的关系,两个类处于不平等的层次上,一个代表整体,一个代表局部。体现的是has-a的关系。 + +UML表示:使用空心菱形箭头表示。 + +![](https://images2015.cnblogs.com/blog/422101/201609/422101-20160928074739125-1256516479.png) + +4、组合关系 + +组合关系也是关联关系的一种,**比聚合关系更强的关系**。组合关系体现的是一种contains-a的关系,同样体现的是整体和局部的关系,但是整体和局部是不可分的,整体的生命周期结束也就意味着部分的生命周期的结束。 + +UML表示:使用实心菱形箭头表示。 + +![](https://images2015.cnblogs.com/blog/422101/201609/422101-20160928074757360-1817412823.png) + + +5、实现关系 + +指的是类和接口之间的关系,一个类实现另外一个接口,实现接口的方法,添加自己的新功能。 + +UML表示:使用虚线+三角形表示 + +![](https://images2015.cnblogs.com/blog/422101/201609/422101-20160928074410531-1863856350.png) + +6、继承关系 + +指的是类和类之间、接口和接口之间的关系。子类全部继承父类的方法和属性。 + +UML表示:使用实线+三角形表示 + +![](https://images2015.cnblogs.com/blog/422101/201609/422101-20160928074329344-1140195322.png) + # 创建型模式 创建型模式主要是和创建对象相关的一些设计模式 @@ -90,3 +183,250 @@ JVM的指令重排序可能导致执行顺序编程1-3-2, 在多线程情况下 ## 建造者(生成器)模式 +目的:封装一个对象的构造过程,允许按步骤构造 + +类图:在建造者模式中,通过抽象Builder对象来一步步建造 + +![](/pics/13b0940e-d1d7-4b17-af4f-b70cb0a75e08.png) + +例如JDK中的StringBuilder就是采用建造者模式实现的。 + +## 原型模式 + +目的:使用原型实例指定要创建对象的类型,然后通过复制这个原型来创建新对象,**即通过原型模式创建复杂对象** + +``` java +public class ConcretePrototype extends Prototype { + + private String filed; + + public ConcretePrototype(String filed) { + this.filed = filed; + } + + @Override + Prototype myClone() { + return new ConcretePrototype(filed); + } + + @Override + public String toString() { + return filed; + } +} +``` + +![](/pics/a40661e4-1a71-46d2-a158-ff36f7fc3331.png) + +java.lang.Object#clone()采用的就是原型模式 + +# 行为型模式 + +行为型设计模式主要是表示类和对象如何交互,以及如何划分责任和算法。 + +## 责任链模式 + +目的:将请求的发送者和接收者解耦,使得多个对象都有处理这个请求的机会。 + +类图:定义一个抽象Handler类,实现具体的Handler类来处理请求。 + +![](/pics/691f11eb-31a7-46be-9de1-61f433c4b3c7.png) + +JDK + +java.util.logging.Logger#log() +Apache Commons Chain +javax.servlet.Filter#doFilter() + +## 命令模式 + +目的:将命令封装成对象中,以便使用命令来参数化其它对象,或者将命令对象放入队列中进行排队,或者将命令对象的操作记录到日志中,以及支持可撤销的操作。 + +类图: + +![](/pics/ae1b27b8-bc13-42e7-ac12-a2242e125499.png) + +JDK +java.lang.Runnable +Netflix Hystrix +javax.swing.Action + +## 解释器模式 + +目的:创建语言的解释器,通常有语言的语法和语法分析来定义 + +![](/pics/794239e3-4baf-4aad-92df-f02f59b2a6fe.png) + +JDK +java.util.Pattern +java.text.Normalizer +All subclasses of java.text.Format +javax.el.ELResolver + +## 迭代器模式 + +目的:提供一种顺序访问对象元素的方法,并且不暴露聚合对象的内部表示 + +![](/pics/b0f61ac2-a4b6-4042-9cf0-ccf4238c1ff7.png) + +## 中介者模式 + +目的:集中相关对象之间复杂的沟通和控制方式 + +类图: +- Mediator:中介者,定义一个接口用于与各同事(Colleague)对象通信。 +- Colleague:同事,相关对象 + +![](/pics/d0afdd23-c9a5-4d1c-9b3d-404bff3bd0d1.png) + +## 备忘录模式 + +目的:在不违反封装的情况下获得对象的内部状态,从而在需要的时候可以将对象恢复到最初状态。 + +类图: + +- Originator:原始对象 +- Caretaker:负责保存好备忘录 +- Menento:备忘录,存储原始对象的的状态。备忘录实际上有两个接口,一个是提供给 Caretaker 的窄接口:它只能将备忘录传递给其它对象;一个是提供给 Originator 的宽接口,允许它访问到先前状态所需的所有数据。理想情况是只允许 Originator 访问本备忘录的内部状态。 + +![](/pics/867e93eb-3161-4f39-b2d2-c0cd3788e194.png) + + +## 观察者模式 + +目的:定义对象之间的**一对多依赖**,当一个对象状态改变时,它所有依赖都会受到通知并且自动更新状态。 + +类图: + +![](/pics/0df5d84c-e7ca-4e3a-a688-bb8e68894467.png) + +JDK +java.util.Observer +java.util.EventListener +javax.servlet.http.HttpSessionBindingListener +RxJava + +## 状态模式 + +目的:允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它所属的类。 + +类图: + +![](/pics/c5085437-54df-4304-b62d-44b961711ba7.png) + +## 策略模式 + +目的:定义一些列算法,封装每个算法,并使他们可以互换。策略模式可以让算法独立于使用它的客户端。 + +类图: + +- Strategy 接口定义了一个算法族,它们都具有 behavior() 方法。 +- Context 是使用到该算法族的类,其中的 doSomething() 方法会调用 behavior(),setStrategy(in Strategy) 方法可以动态地改变 strategy 对象,也就是说能动态地改变 Context 所使用的算法。 + +![](/pics/1fc969e4-0e7c-441b-b53c-01950d2f2be5.png) + +**与状态模式的比较** +状态模式的类图和策略模式类似,并且都是能够动态改变对象的行为。但是状态模式是通过状态转移来改变 Context 所组合的 State 对象,而策略模式是通过 Context 本身的决策来改变组合的 Strategy 对象。所谓的状态转移,是指 Context 在运行过程中由于一些条件发生改变而使得 State 对象发生改变,注意必须要是在运行过程中。 + +状态模式主要是用来解决状态转移的问题,当状态发生转移了,那么 Context 对象就会改变它的行为;而策略模式主要是用来封装一组可以互相替代的算法族,并且可以根据需要动态地去替换 Context 使用的算法。 + +## 模板方法 + +目的:定义算法框架,并将一些步骤的实现**延迟到子类**。通过模板方法,子类可以重新定义算法的某些步骤,而不用改变算法的结构。 + +类图: + +![](/pics/c3c1c0e8-3a78-4426-961f-b46dd0879dd8.png) + +## 访问者模式 + +目的:为一个对象结构(比如组合结构)增加新能力。 + +类图: + +- Visitor:访问者,为每一个 ConcreteElement 声明一个 visit 操作 +- ConcreteVisitor:具体访问者,存储遍历过程中的累计结果 +- ObjectStructure:对象结构,可以是组合结构,或者是一个集合。 + +![](/pics/ec923dc7-864c-47b0-a411-1f2c48d084de.png) + +# 结构型 + +结构型模式是用于类或者对象之间的组合关系。 + +## 适配器模式 + +目的:把一个类的接口转换成另外一个用户需要的接口 + +类图: + +![](/pics/0f754c1d-b5cb-48cd-90e0-4a86034290a1.png) + +## 桥接模式 + +目的:将抽象和实现分离,可以独立变化 + +类图: + +- Abstraction: 定义抽象类的接口 +- Implementor: 定义实现类的接口 + +![](/pics/c2cbf5d2-82af-4c78-bd43-495da5adf55f.png) + +## 组合模式 + +目的:将对象组合成树形结构来表示“整体/部分”层次关系,允许用户以相同的方式处理单独对象和组合对象。 + +类图: + +![](/pics/3fb5b255-b791-45b6-8754-325c8741855a.png) + +JDK: + +List +Map + +## 装饰者模式 + +目的:为对象动态添加功能 + +类图:装饰者(Decorator)和具体组件(ConcreteComponent)都继承自组件(Component),具体组件的方法实现不需要依赖于其它对象,而装饰者组合了一个组件,这样它可以装饰其它装饰者或者具体组件。 + +![](/pics/137c593d-0a9e-47b8-a9e6-b71f540b82dd.png) + +## 外观模式 + +目的:提供了一个统一的接口,用来访问子系统中的一群接口,从而让子系统更容易使用。 + +类图: + +![](/pics/f9978fa6-9f49-4a0f-8540-02d269ac448f.png) + +## 享元模式 + +目的:利用共享的方式来支持大量细粒度的对象,这些对象的一部分内部状态是相同的。 + +类图: + +- Flyweight:享元对象 +- IntrinsicState:内部状态,享元对象共享内部状态 +- ExtrinsicState:外部状态,每个享元对象的外部状态不同 + +![](/pics/d52270b4-9097-4667-9f18-f405fc661c99.png) + +## 代理模式 + +目的:控制对其他对象的访问。 + +类图: + +![](/pics/a6c20f60-5eba-427d-9413-352ada4b40fe.png) + +**代理模式和装饰者模式的区别** +从功能上看,代理模式实现被代理类的简介访问,装饰者模式则是动态添加类的功能 +从类图上看,代理类和装饰类均与目标类实现了同一接口,但是代理类拥有真实目标类的成员(关联关系) + +# 参考链接 + +- [JAVA设计模式总结之23种设计模式](https://www.cnblogs.com/pony1223/p/7608955.html) +