Skip to content

Commit 713eb12

Browse files
committed
thread
1 parent 53a9ff8 commit 713eb12

771 files changed

Lines changed: 1612 additions & 446 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
88.6 KB
Loading

docs/design-pattern/Adapter-Pattern.md

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
在不想改变原有代码逻辑的情况下,如何解决呢?
1212

13-
这时候我们就可以创建一个「适配器」。这是一个特殊的对象, 能够转换对象接口, 使其能与其他对象进行交互。
13+
这时候我们就可以创建一个「**适配器**」。这是一个特殊的对象, 能够转换对象接口, 使其能与其他对象进行交互。
1414

1515
适配器模式通过封装对象将复杂的转换过程隐藏于幕后。 被封装的对象甚至察觉不到适配器的存在。
1616

@@ -28,16 +28,16 @@
2828

2929
## 基本介绍
3030

31-
- 适配器模式将一个类的接口,转换成客户期望的另外一个接口。适配器让原本接口不兼容的类可以合作无间。也可以叫包装器(Wrapper)
31+
- 适配器模式将一个类的接口,转换成客户期望的另外一个接口。适配器让原本接口不兼容的类可以合作无间。也可以叫包装器(Wrapper)
3232

33-
- **适配器模式**是一种结构型设计模式, 它能使接口不兼容的对象能够相互合作
33+
- **适配器模式**是一种结构型设计模式, 它能使接口不兼容的对象能够相互合作
3434
- 主要分为两类:类适配器模式、对象适配器模式
3535

3636

3737

3838
## 工作原理
3939

40-
- 适配器模式:将一个类的接口转换成另一种接口.让原本接口不兼容的类可以兼容
40+
- 适配器模式:将一个类的接口转换成另一种接口让原本接口不兼容的类可以兼容
4141
- 从用户的角度看不到被适配者,是解耦的
4242
- 用户调用适配器转化出来的目标接口方法,适配器再调用被适配者的相关接口方法
4343
- 用户收到反馈结果,感觉只是和目标接口交互
@@ -207,7 +207,7 @@ Java 虽然不能实现标准的类适配器,但是有一种变通的方式,
207207

208208
220V 的交流电相当于被适配者 Adaptee,我们的目标 Target 是 5V 直流电,充电器本身相当于一个 Adapter,将220V 的输入电压变换为 5V 输出。
209209

210-
1. 首先是我们的名用电(我国是 220V,当然还可以有其他国家的其他准备,可随时扩展)
210+
1. 首先是我们的民用电(我国是 220V,当然还可以有其他国家的其他准备,可随时扩展)
211211

212212
```java
213213
public class Volatage220V {
@@ -299,7 +299,7 @@ Spring 源码中搜关键字`Adapter` 会出现很多实现类,SpringMVC 中
299299

300300
![qsli.github.io](https://tva1.sinaimg.cn/large/007S8ZIlly1gfjqoif1ddj30vq0ij0uq.jpg)
301301

302-
Spring MVC中的适配器模式主要用于执行目标 `Controller` 中的请求处理方法。
302+
Spring MVC 中的适配器模式主要用于执行目标 `Controller` 中的请求处理方法。
303303

304304
在Spring MVC中,`DispatcherServlet` 作为用户,`HandlerAdapter` 作为期望接口,具体的适配器实现类用于对目标类进行适配,`Controller` 作为需要适配的类。
305305

@@ -322,11 +322,11 @@ if(mappedHandler.getHandler() instanceof MultiActionController){
322322
```java
323323
public class DispatcherServlet extends FrameworkServlet {
324324
//......
325-
//维护所有HandlerAdapter类的集合
325+
//维护所有HandlerAdapter类的集合
326326
@Nullable
327327
private List<HandlerAdapter> handlerAdapters;
328328

329-
//初始化handlerAdapters
329+
//初始化handlerAdapters
330330
private void initHandlerAdapters(ApplicationContext context) {
331331
this.handlerAdapters = null;
332332
if (this.detectAllHandlerAdapters) {
@@ -355,15 +355,15 @@ public class DispatcherServlet extends FrameworkServlet {
355355
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
356356
//...
357357

358-
//获得controller对应的适配器
358+
//获得controller对应的适配器
359359
HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
360360

361-
//调用适配器的handler方法处理请求,并返回ModelAndView
361+
//调用适配器的handler方法处理请求,并返回ModelAndView
362362
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
363363
//...
364364
}
365365

366-
//返回对应的controller的处理器
366+
//返回对应的controller的处理器
367367
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
368368
if (this.handlerAdapters != null) {
369369
Iterator var2 = this.handlerAdapters.iterator();
@@ -396,14 +396,14 @@ public interface HandlerAdapter {
396396
再来屡一下这个流程:
397397

398398
1. 首先是适配器接口 DispatchServlet 中有一个集合维护所有的 HandlerAdapter,如果配置文件中没有对适配器进行配置,那么 DispatchServlet 会在创建时对该变量进行初始化,注册所有默认的 HandlerAdapter
399-
2. 当一个请求过来时,DispatchServlet 会根据传过来的 handler 类型从该集合中寻找对应的 HandlerAdapter子类进行处理,并且调用它的 handler() 方法
400-
3. 对应的 HandlerAdapter 中的 handler() 方法又会执行对应 ControllerhandleRequest() 方法
399+
2. 当一个请求过来时,DispatchServlet 会根据传过来的 handler 类型从该集合中寻找对应的 HandlerAdapter子类进行处理,并且调用它的 `handler()` 方法
400+
3. 对应的 HandlerAdapter 中的 `handler()` 方法又会执行对应 Controller 的 `handleRequest()` 方法
401401

402402
适配器与 handler 有对应关系,而各个适配器又都是适配器接口的实现类,因此,它们都遵循相同的适配器标准,所以用户可以按照相同的方式,通过不同的 handler 去处理请求。 当然了,Spring 框架中也为我们定义了一些默认的 Handler 对应的适配器。
403403

404404
![](https://tva1.sinaimg.cn/large/007S8ZIlly1gfjrbrv96pj31ck0j0dl6.jpg)
405405

406-
通过适配器模式我们将所有的 `controller` 统一交给 `HandlerAdapter` 处理,免去了写大量的 `if-else` 语句对 `Controller` 进行判断,也更利于扩展新的 `Controller` 类型。
406+
通过适配器模式我们将所有的 `controller` 统一交给 `HandlerAdapter` 处理,免去了写大量的 `if-else` 语句对 `Controller` 进行判断,也更利于扩展新的 `Controller` 类型。
407407

408408

409409

docs/design-pattern/Chain-of-Responsibility-Pattern.md

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# 责任链模式
22

33
责任链,顾名思义,就是用来处理相关事务责任的一条执行链,执行链上有多个节点,每个节点都有机会(条件匹配)处理请求事务,如果某个节点处理完了就可以根据实际业务需求传递给下一个节点继续处理或者返回处理完毕。
4+
45
这种模式给予请求的类型,对请求的发送者和接收者进行解耦。属于行为型模式。
56

67
在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。
@@ -25,7 +26,7 @@ public void test(int i, Request request){
2526
}
2627
```
2728

28-
代码的业务逻辑是这样的,方法有两个参数:整数 i 和一个请求 request,根据 i 的值来决定由谁来处理 request,如果 i==1,由 Handler1来处理,如果 i==2,由 Handler2 来处理,以此类推。在编程中,这种处理业务的方法非常常见,所有处理请求的类由if…else…条件判断语句连成一条责任链来对请求进行处理,相信大家都经常用到。这种方法的优点是非常直观,简单明了,并且比较容易维护,但是这种方法也存在着几个比较令人头疼的问题:
29+
代码的业务逻辑是这样的,方法有两个参数:整数 i 和一个请求 request,根据 i 的值来决定由谁来处理 request,如果 i==1,由 Handler1来处理,如果 i==2,由 Handler2 来处理,以此类推。在编程中,这种处理业务的方法非常常见,所有处理请求的类由 if…else… 条件判断语句连成一条责任链来对请求进行处理,相信大家都经常用到。这种方法的优点是非常直观,简单明了,并且比较容易维护,但是这种方法也存在着几个比较令人头疼的问题:
2930

3031
- **代码臃肿**:实际应用中的判定条件通常不是这么简单地判断是否为1或者是否为2,也许需要复杂的计算,也许需要查询数据库等等,这就会有很多额外的代码,如果判断条件再比较多,那么这个if…else…语句基本上就没法看了。
3132
- **耦合度高**:如果我们想继续添加处理请求的类,那么就要继续添加if…else…判定条件;另外,这个条件判定的顺序也是写死的,如果想改变顺序,那么也只能修改这个条件语句。
@@ -46,7 +47,7 @@ public void test(int i, Request request){
4647

4748
## 角色
4849

49-
- **Handler**: 抽象处理类,抽象处理类中主要包含一个指向下一处理类的成员变量nextHandler和一个处理请求的方法handRequest,handRequest方法的主要主要思想是,如果满足处理的条件,则有本处理类来进行处理,否则由nextHandler来处理
50+
- **Handler**: 抽象处理类,抽象处理类中主要包含一个指向下一处理类的成员变量 nextHandler 和一个处理请求的方法 handRequest,handRequest 方法的主要主要思想是,如果满足处理的条件,则由本处理类来进行处理,否则由 nextHandler 来处理
5051
- **ConcreteHandler**: 具体处理类主要是对具体的处理逻辑和处理的适用条件进行实现。具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。由于具体处理者持有对下家的引用,因此,如果需要,具体处理者可以访问下家
5152
- **Client**:客户端
5253

@@ -127,7 +128,7 @@ public class Client {
127128
ConcreteHandler1 handler1 = new ConcreteHandler1(1);
128129
ConcreteHandler2 handler2 = new ConcreteHandler2(2);
129130
ConcreteHandler3 handler3 = new ConcreteHandler3(3);
130-
//处理者构成一个环形
131+
//处理者构成一个环形
131132
handler1.setNextHandler(handler2);
132133
handler2.setNextHandler(handler3);
133134

@@ -146,7 +147,7 @@ public class Client {
146147

147148
比如
148149

149-
- 程序员要请3天以上的假期,在OA申请,需要直接主管、总监、HR 层层审批后才生效。类似的采购审批、报销审批。。。
150+
- 程序员要请 3 天以上的假期,在 OA 申请,需要直接主管、总监、HR 层层审批后才生效。类似的采购审批、报销审批。。。
150151
- 美团在外卖营销业务中资源位展示的逻辑 https://tech.meituan.com/2020/03/19/design-pattern-practice-in-marketing.html
151152

152153

@@ -205,9 +206,9 @@ public final class ApplicationFilterChain implements FilterChain {
205206

206207
FilterChain 就是一条过滤链。其中每个过滤器(Filter)都可以决定是否执行下一步。过滤分两个方向,进和出:
207208

208-
进:在把ServletRequestServletResponse交给Servlet的service方法之前,需要进行过滤
209+
- 进:在把 ServletRequestServletResponse 交给 Servlet 的 service 方法之前,需要进行过滤
209210

210-
出:在service方法完成后,往客户端发送之前,需要进行过滤
211+
- 出:在service方法完成后,往客户端发送之前,需要进行过滤
211212

212213

213214

@@ -265,7 +266,7 @@ protected void doDispatch(HttpServletRequest request, HttpServletResponse respon
265266
}
266267
```
267268

268-
- SpringMVC 请求的流程中,执行了拦截器相关方法 interceptor.preHandler 等等
269+
- SpringMVC 请求的流程中,执行了拦截器相关方法 `interceptor.preHandler` 等等
269270
- 在处理 SpringMVC 请求时,使用到职责链模式还使用到适配器模式
270271
- HandlerExecutionChain 主要负责的是请求拦截器的执行和请求处理,但是他本身不处理请求,只是将请求分配给链上注册处理器执行,这是职责链实现方式,减少职责链本身与处理逻辑之间的耦合,规范了处理流程
271272
- HandlerExecutionChain 维护了 HandlerInterceptor 的集合, 可以向其中注册相应的拦截器
@@ -276,7 +277,7 @@ protected void doDispatch(HttpServletRequest request, HttpServletResponse respon
276277

277278
## 总结
278279

279-
责任链模式其实就是一个灵活版的 ifelse…语句,它就是将这些判定条件的语句放到了各个处理类中,这样做的优点是比较灵活了,但同样也带来了风险,比如设置处理类前后关系时,一定要特别仔细,搞对处理类前后逻辑的条件判断关系,并且注意不要在链中出现循环引用的问题。
280+
**责任链模式其实就是一个灵活版的 ifelse…语句**,它就是将这些判定条件的语句放到了各个处理类中,这样做的优点是比较灵活了,但同样也带来了风险,比如设置处理类前后关系时,一定要特别仔细,搞对处理类前后逻辑的条件判断关系,**并且注意不要在链中出现循环引用的问题**
280281

281282
**优点**
282283

docs/design-pattern/Decorator-Pattern.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
# 装饰模式——JDK和Spring是如何杜绝继承滥用的
1+
# 装饰模式——看看 JDK 和 Spring 是如何杜绝继承滥用的
22

3-
《Head First 设计模式》中是这么形容装饰者模式——“**给爱用继承的人一个全新的设计眼界**”,拒绝继承滥用,从装饰者模式开始。
3+
《Head First 设计模式》中是这么形容装饰者模式的——“**给爱用继承的人一个全新的设计眼界**”,拒绝继承滥用,从装饰者模式开始。
44

55
装饰者模式允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于**结构型模式**,它是作为现有的类的一个包装。
66

@@ -15,7 +15,7 @@
1515
一般有两种方式可以实现给一个类或对象增加行为:
1616

1717
- 继承机制,使用继承机制是给现有类添加功能的一种有效途径,通过继承一个现有类可以使得子类在拥有自身方法的同时还拥有父类的方法。但是这种方法是静态的,用户不能控制增加行为的方式和时机。
18-
- 关联机制,即将一个类的对象嵌入另一个对象中,由另一个对象来决定是否调用嵌入对象的行为以便扩展自己的行为,我们称这个嵌入的对象为装饰器(Decorator)
18+
- 关联机制,即将一个类的对象嵌入另一个对象中,由另一个对象来决定是否调用嵌入对象的行为以便扩展自己的行为,我们称这个嵌入的对象为**装饰器**(Decorator)
1919

2020
装饰模式以对客户透明的方式动态地给一个对象附加上更多的责任,换言之,客户端并不会觉得对象在装饰前和装饰后有什么不同。装饰模式可以在不需要创造更多子类的情况下,将对象的功能加以扩展。
2121

@@ -178,7 +178,7 @@ public class Client {
178178
}
179179
```
180180

181-
输出
181+
输出
182182

183183
```
184184
煎饼果子花费:8.0元
@@ -246,7 +246,7 @@ public class InputTest {
246246

247247
### Servlet 中的装饰者模式
248248

249-
Servlet API源自于4个实现类,它很少被使用,但是十分强大:`ServletRequestWrapper``ServletResponseWrapper`以及 `HttpServletRequestWrapper``HttpServletResponseWrapper`
249+
Servlet API 源自于 4 个实现类,它很少被使用,但是十分强大:`ServletRequestWrapper``ServletResponseWrapper`以及 `HttpServletRequestWrapper``HttpServletResponseWrapper`
250250

251251
比如`ServletRequestWrapper``ServletRequest` 接口的简单实现,开发者可以继承 `ServletRequestWrapper` 去扩展原来的`request`
252252

@@ -269,9 +269,9 @@ public class ServletRequestWrapper implements ServletRequest {
269269

270270
### spring 中的装饰者模式
271271

272-
Spring 的 `ApplicationContext` 中配置所有的 `DataSource`。 这些 DataSource 可能是各种不同类型的, 比如不同的数据库: Oracle、 SQL Server、 MySQL 等, 也可能是不同的数据源。 然后 SessionFactory 根据客户的每次请求, 将 DataSource 属性设置成不同的数据源, 以到达切换数据源的目的
272+
Spring 的 `ApplicationContext` 中配置所有的 `DataSource`。 这些 DataSource 可能是各种不同类型的, 比如不同的数据库: Oracle、 SQL Server、 MySQL 等, 也可能是不同的数据源。 然后 SessionFactory 根据客户的每次请求, 将 DataSource 属性设置成不同的数据源, 以达到切换数据源的目的
273273

274-
spring 的命名体现:Spring 中用到的包装器模式在类名上有两种表现: 一种是类名中含有 `Wrapper`, 另一种是类名中含有`Decorator`。 基本上都是动态地给一个对象添加一些额外的职责,比如
274+
Spring 的命名体现:Spring 中用到的包装器模式在类名上有两种表现: 一种是类名中含有 `Wrapper`, 另一种是类名中含有 `Decorator`。 基本上都是动态地给一个对象添加一些额外的职责,比如
275275

276276
- `org.springframework.cache.transaction` 包下的 `TransactionAwareCacheDecorator`
277277
- `org.springframework.session.web.http` 包下的 `SessionRepositoryFilter` 内部类 `SessionRepositoryRequestWrapper`
@@ -290,7 +290,7 @@ Mybatis 的缓存模块中,使用了装饰器模式的变体,其中将 `Deco
290290

291291
## 总结
292292

293-
装饰模式的本质:动态组合
293+
装饰模式的本质:**动态组合**
294294

295295
动态组合是手段,组合才是目的。这里的组合有两个意思,一个是动态功能的组合,也就是动态进行装饰器的组合;另外一个是指对象组合,通过对象组合来实现为被装饰对象透明的增加功能。
296296

@@ -311,7 +311,7 @@ Mybatis 的缓存模块中,使用了装饰器模式的变体,其中将 `Deco
311311
### 何时选用
312312

313313
- 如果需要在不影响其他对象的情况下,以动态、透明的方式给对象添加职责,可以使用装饰模式
314-
- 当不能采用继承的方式对系统进行扩展或者采用继承不利于系统扩展和维护时可以使用装饰模式。不能采用继承的情况主要有两类:第一类是系统中存在大量独立的扩展,为支持每一种扩展或者扩展之间的组合将产生大量的子类,使得子类数目呈爆炸性增长;第二类是因为类已定义为不能被继承(如Java语言中的final类
314+
- 当不能采用继承的方式对系统进行扩展或者采用继承不利于系统扩展和维护时可以使用装饰模式。不能采用继承的情况主要有两类:第一类是系统中存在大量独立的扩展,为支持每一种扩展或者扩展之间的组合将产生大量的子类,使得子类数目呈爆炸性增长;第二类是因为类已定义为不能被继承(如 Java 语言中的 final 类
315315

316316
------
317317

0 commit comments

Comments
 (0)