|
@@ -1,7 +1,7 @@
|
|
-### 常用的设计模式
|
|
|
|
|
|
+## 常用的设计模式
|
|
---
|
|
---
|
|
|
|
|
|
-#### 单例模式
保证一个类仅有一个实例,并提供一个访问它的全局访问点
|
|
|
|
|
|
+### 单例模式
保证一个类仅有一个实例,并提供一个访问它的全局访问点
|
|
```
|
|
```
|
|
public class SingletonClass{
|
|
public class SingletonClass{
|
|
private static SingletonClass instance=null;
|
|
private static SingletonClass instance=null;
|
|
@@ -16,16 +16,16 @@ public class SingletonClass{
|
|
return instance;
|
|
return instance;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-```
#### 工厂模式
|
|
|
|
|
|
+```
[如何实现一个正确的单例模式](https://mp.weixin.qq.com/s/2ARZEkUZWKN0fxHfkayYHA)
### 工厂模式
|
|
|
|
|
|
**类图:**
|
|
**类图:**
|
|
-

#### 装饰模式
装饰者模式,在保持原有功能不变的情况下将一个类重新装饰,使其具有更强大的功能,用一句成语形容“锦上添花”。
|
|
|
|
|
|
+

### 装饰模式
装饰者模式,在保持原有功能不变的情况下将一个类重新装饰,使其具有更强大的功能,用一句成语形容“锦上添花”。
|
|
**类结构:**
|
|
**类结构:**
|
|
|
|
|
|

Component:抽象组件,定义了一组抽象的接口,指定了被装饰的组件都有哪些功能。
|
|

Component:抽象组件,定义了一组抽象的接口,指定了被装饰的组件都有哪些功能。
|
|
ComponentImpl:抽象组件实现类,完成了基本的功能实现。
Decorator:装饰器角色,持有Component的实例引用,有点递归的感觉。
伪代码:
|
|
ComponentImpl:抽象组件实现类,完成了基本的功能实现。
Decorator:装饰器角色,持有Component的实例引用,有点递归的感觉。
伪代码:
|
|
```
Component c=new ComponentImpl();
Decorator d1=new Decorator();
d1.setComponent(c);
Decorator d2=new Decorator();
d2.setComponent(d1);
Decorator d3=new Decorator();
d3.setComponent(d2);
Decorator d4=new Decorator();
d4.setComponent(d3);
d4.methodA();
|
|
```
Component c=new ComponentImpl();
Decorator d1=new Decorator();
d1.setComponent(c);
Decorator d2=new Decorator();
d2.setComponent(d1);
Decorator d3=new Decorator();
d3.setComponent(d2);
Decorator d4=new Decorator();
d4.setComponent(d3);
d4.methodA();
|
|
-
```
装饰者模式和适配器模式有点类似,都是包装(wrapper)了一个类,但目地却不相同。适配器模式是将一个接口转换成另一个接口,从而达成匹配。而装饰者模式并没有改变原来的接口,而是改变原有对象的处理方法,借助递归提升性能。
#### 适配器模式
|
|
|
|
|
|
+
```
装饰者模式和适配器模式有点类似,都是包装(wrapper)了一个类,但目地却不相同。适配器模式是将一个接口转换成另一个接口,从而达成匹配。而装饰者模式并没有改变原来的接口,而是改变原有对象的处理方法,借助递归提升性能。
### 适配器模式
|
|
适配器模式就是一个类的接口不能被客户端接受,需要转换为另一种接口,从而使两个不匹配的接口能在一起工作。
|
|
适配器模式就是一个类的接口不能被客户端接受,需要转换为另一种接口,从而使两个不匹配的接口能在一起工作。
|
|
**类结构**
|
|
**类结构**
|
|

Adaptee:源接口,需要适配的接口
|
|

Adaptee:源接口,需要适配的接口
|
|
@@ -36,27 +36,27 @@ public class SingletonClass{
|
|
**适用场景:**
|
|
**适用场景:**
|
|
比如查物流信息,由于物流公司的系统都是各自独立,在编程语言和交互方式上有很大差异,需要针对不同的物流公司做单独适配,同时结合不同公司的系统性能,配置不同的响应超时时间
|
|
比如查物流信息,由于物流公司的系统都是各自独立,在编程语言和交互方式上有很大差异,需要针对不同的物流公司做单独适配,同时结合不同公司的系统性能,配置不同的响应超时时间
|
|
|
|
|
|
-
#### 观察者模式
|
|
|
|
|
|
+
### 观察者模式
|
|
观察者模式通常也叫发布—订阅模式,或者事件监听模式,定义一对多的依赖关系,让多个观察者对象同时监听一个主题对象,如果这个主题对象的状态发生变化时,会通知所有的观察者对象。
异步消息(MQ、activeMQ)都是基于这种模式
**类结构图:**
|
|
观察者模式通常也叫发布—订阅模式,或者事件监听模式,定义一对多的依赖关系,让多个观察者对象同时监听一个主题对象,如果这个主题对象的状态发生变化时,会通知所有的观察者对象。
异步消息(MQ、activeMQ)都是基于这种模式
**类结构图:**
|
|
|
|
|
|

* Subject:主题类,将所有的观察者对象保存在一个List集合中,并提供增、删的方法,以及状态变化后的通知方法。
* Observer:观察者的抽象接口,提供了一个抽象的动作方法,具体的业务由子类来实现
* ConcreteObserver:具体的观察者,负责实现自己的业务动作
* ConcreteSubject:具体的主题类,在内部状态发生变化时,给所有登记过的观察者发出通知。
**优点:**
|
|

* Subject:主题类,将所有的观察者对象保存在一个List集合中,并提供增、删的方法,以及状态变化后的通知方法。
* Observer:观察者的抽象接口,提供了一个抽象的动作方法,具体的业务由子类来实现
* ConcreteObserver:具体的观察者,负责实现自己的业务动作
* ConcreteSubject:具体的主题类,在内部状态发生变化时,给所有登记过的观察者发出通知。
**优点:**
|
|
-
* 解耦,将耦合的双方都依赖于抽象类,而不是依赖于具体。从而使得各自的变化不会影响另一边的变化。
* Observer采用的是抽象类,这样的好处是可以将多个子类相同的代码逻辑抽取出来,放到抽象类中
#### 责任链模式
|
|
|
|
|
|
+
* 解耦,将耦合的双方都依赖于抽象类,而不是依赖于具体。从而使得各自的变化不会影响另一边的变化。
* Observer采用的是抽象类,这样的好处是可以将多个子类相同的代码逻辑抽取出来,放到抽象类中
### 责任链模式
|
|
责任链模式就是很多对象由每个对象对其下家的引用串连起来形成一条链,请求在这条链上传递,直到最终处理完。就象一根水管一样,水从一端流入,会经过一系列的阀门,最终从另一端流出。如果有一个阀门关着,水都流不出来。
|
|
责任链模式就是很多对象由每个对象对其下家的引用串连起来形成一条链,请求在这条链上传递,直到最终处理完。就象一根水管一样,水从一端流入,会经过一系列的阀门,最终从另一端流出。如果有一个阀门关着,水都流不出来。
|
|
**链上的节点可以控制,根据是否执行分为两种情况:**
|
|
**链上的节点可以控制,根据是否执行分为两种情况:**
|
|
|
|
|
|
* 找到对应的点,执行,跳出。如:for循环的break
* 所有的节点都执行一遍,上个节点的返回结果作为下个节点的入参
|
|
* 找到对应的点,执行,跳出。如:for循环的break
* 所有的节点都执行一遍,上个节点的返回结果作为下个节点的入参
|
|
http://blog.csdn.net/itomge/article/details/20792567
|
|
http://blog.csdn.net/itomge/article/details/20792567
|
|
-
#### 策略模式
|
|
|
|
|
|
+
### 策略模式
|
|
策略模式通常是指完成某个操作可能会有多种方法,适用于多种场合。我们需要把每个操作方法当做一个实现策略,调用者可根据需要(特定的规则)选择合适的策略
|
|
策略模式通常是指完成某个操作可能会有多种方法,适用于多种场合。我们需要把每个操作方法当做一个实现策略,调用者可根据需要(特定的规则)选择合适的策略
|
|
**结构类图:**
|
|
**结构类图:**
|
|

* Context:使用不同的策略环境,根据自身的条件选择不同的策略实现类来完成所需要的操作。他持有一个策略实例的引用
* Strategy:抽象策略,定义每个策略都要实现的方法
* Realize1,Realize2:负责实现抽象策略中定义的策略方法。
|
|

* Context:使用不同的策略环境,根据自身的条件选择不同的策略实现类来完成所需要的操作。他持有一个策略实例的引用
* Strategy:抽象策略,定义每个策略都要实现的方法
* Realize1,Realize2:负责实现抽象策略中定义的策略方法。
|
|
```
例子:
@Override
@Enhancement({ @Capability(type = CapabilityTypeEnum.INVOCATION_STATS) })
public void sendGoods(SendGoodsParam param) throws ServiceException {
if (null == param || null == param.getId()) {
this.throwInvalidError(ErrorCodeEnum.NULL_PARAM, null, param);
}
TradeFlowService t = createTradeFlowServiceByOrderId(param.getId());
t.sendGoods(param);
}
|
|
```
例子:
@Override
@Enhancement({ @Capability(type = CapabilityTypeEnum.INVOCATION_STATS) })
public void sendGoods(SendGoodsParam param) throws ServiceException {
if (null == param || null == param.getId()) {
this.throwInvalidError(ErrorCodeEnum.NULL_PARAM, null, param);
}
TradeFlowService t = createTradeFlowServiceByOrderId(param.getId());
t.sendGoods(param);
}
|
|
```
createTradeFlowServiceByOrderId方法会根据”订单号的长短“选择具体的子策略
|
|
```
createTradeFlowServiceByOrderId方法会根据”订单号的长短“选择具体的子策略
|
|
-
* 长订单号:tpTradeFlowService
* 短订单号:unifyTradeFlowService
彼此子策略实现互不干扰,有效达到隔离效果。
#### 合成模式
|
|
|
|
|
|
+
* 长订单号:tpTradeFlowService
* 短订单号:unifyTradeFlowService
彼此子策略实现互不干扰,有效达到隔离效果。
### 合成模式
|
|
可以控制某资源同时被访问的个数。例如连接池中通常要控制创建连接的个数。
|
|
可以控制某资源同时被访问的个数。例如连接池中通常要控制创建连接的个数。
|
|
tryAcquire方法,获得锁
|
|
tryAcquire方法,获得锁
|
|
release方法,释放锁
|
|
release方法,释放锁
|
|
-
#### 模板模式
|
|
|
|
|
|
+
### 模板模式
|
|
应用场景很多,尤其是在框架设计中,提供了一个方便的开发程序的模板,你只要实现模板中的一些接口或方法就能完成一个复杂的任务。
|
|
应用场景很多,尤其是在框架设计中,提供了一个方便的开发程序的模板,你只要实现模板中的一些接口或方法就能完成一个复杂的任务。
|
|
**结构类图:**

* AbstractTemplate:定义一个完整的框架,方法的调用顺序已经确定,但会定义一些抽象的方法留给子类去实现
* SubTemplate:实现抽象模板中定义的抽象方法,从而形成一个完整的流程逻辑
|
|
**结构类图:**

* AbstractTemplate:定义一个完整的框架,方法的调用顺序已经确定,但会定义一些抽象的方法留给子类去实现
* SubTemplate:实现抽象模板中定义的抽象方法,从而形成一个完整的流程逻辑
|
|
```
public TradeFlowActionResult execute(TradeFlowActionParam param, Map context) throws ServiceException {
try { // 业务逻辑校验
this.validateBusinessLogic(param, context);
} catch (ServiceException ex) {
sendGoodsLog.info("SendGoodsAction->validateBusinessLogic got exception. param is " + param, ex);
throw ex;
} catch (RuntimeException ex) {
sendGoodsLog.info("SendGoodsAction->validateBusinessLogic got runtime exception. param is " + param, ex);
throw ex;
}
try {
// 卖家发货业务逻辑
this.sendGoods(param, context);
} catch (ServiceException ex) {
sendGoodsLog.info("SendGoodsAction->sendGoods got exception. param is " + param, ex);
throw ex;
} catch (RuntimeException ex) {
sendGoodsLog.info("SendGoodsAction->sendGoods got runtime exception. param is " + param, ex);
throw ex;
}
try {
// 补充业务(结果不影响核心业务)
this.addition(param, context);
} catch (ServiceException ex) {
sendGoodsLog.info("SendGoodsAction->addition got exception. param is " + param, ex);
throw ex;
} catch (RuntimeException ex) {
sendGoodsLog.info("SendGoodsAction->addition got runtime exception. param is " + param, ex);
throw ex;
}
// 处理结果
return null;
}
|
|
```
public TradeFlowActionResult execute(TradeFlowActionParam param, Map context) throws ServiceException {
try { // 业务逻辑校验
this.validateBusinessLogic(param, context);
} catch (ServiceException ex) {
sendGoodsLog.info("SendGoodsAction->validateBusinessLogic got exception. param is " + param, ex);
throw ex;
} catch (RuntimeException ex) {
sendGoodsLog.info("SendGoodsAction->validateBusinessLogic got runtime exception. param is " + param, ex);
throw ex;
}
try {
// 卖家发货业务逻辑
this.sendGoods(param, context);
} catch (ServiceException ex) {
sendGoodsLog.info("SendGoodsAction->sendGoods got exception. param is " + param, ex);
throw ex;
} catch (RuntimeException ex) {
sendGoodsLog.info("SendGoodsAction->sendGoods got runtime exception. param is " + param, ex);
throw ex;
}
try {
// 补充业务(结果不影响核心业务)
this.addition(param, context);
} catch (ServiceException ex) {
sendGoodsLog.info("SendGoodsAction->addition got exception. param is " + param, ex);
throw ex;
} catch (RuntimeException ex) {
sendGoodsLog.info("SendGoodsAction->addition got runtime exception. param is " + param, ex);
throw ex;
}
// 处理结果
return null;
}
|