设计模式系列文章

java设计模式解析(1) Observer观察者模式
java设计模式解析(2) Proxy代理模式
java设计模式解析(3) Factory工厂模式
java设计模式解析(4) Singleton单例模式
java设计模式解析(5) Delegate委派模式
java设计模式解析(6) Strategy策略模式
java设计模式解析(7) Prototype原型模式
java设计模式解析(8) Template模版模式
java设计模式解析(9) Decorator装饰模式
java设计模式解析(10) Adapter适配模式
java设计模式解析(11) Chain责任链模式
 
 主要内容

1、简述

2、实现代码(Talk is cheap,Show me the code)

3、注意点

1、简述

Chain责任链模式在《设计模式之禅》定义: 使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系。将这些对象连成一条线,并沿着这条链传递该请求,直至有对象处理它为止。

责任链的核心在“链”,由“链”上所有的成员去处理请求并返回结果。 类图中各个角色定义如下:

  • Client:客户端向发起请求,责任链对客户端透明
  • Handler:责任链抽象类,负责定义处理逻辑以及组装责任链机制
  • ConcreteHandler:责任链中的链由多个ConcreteHandler组装而成

结合上述给伪码:

==> Handler类

 public abstract class Handler {
private Handler nextHandler ; public final Response handlerMessage(Request request){
Response response = null ;
// 符合自己处理
if(this.getHandlerLevel().equals(request.getRequestLevel())){
response = this.echo(request) ;
}
// 交由其他人处理
else if (nextHandler != null) {
response = nextHandler.handlerMessage(request) ;
}
return response ;
} // 组装责任链
public void setNextHandler(Handler nextHandler) {
this.nextHandler = nextHandler;
} // 模版方法 由具体的责任链实现者定义
protected abstract Level getHandlerLevel();
protected abstract Response echo(Request request);
}

==> ConcreteHandler1、ConcreteHandler2、ConcreteHandler3三个类代码类似,都是实际责任链一员且通过继承Handler只需要实现自己的逻辑部分。

 public class ConcreteHandler1 extends Handler {
@Override
protected Level getHandlerLevel() {
return null;
} @Override
protected Response echo(Request request) {
return null;
}
}

==> Client客户端发起请求 此时包含了责任链的组装和调用 实际可以增加代理简化Client操作

 public class Client {
public static void main(String[] args) { // 组装责任链
ConcreteHandler1 handler1 = new ConcreteHandler1() ;
ConcreteHandler2 handler2 = new ConcreteHandler2() ;
ConcreteHandler3 handler3 = new ConcreteHandler3() ;
handler1.setNextHandler(handler2);
handler2.setNextHandler(handler3); // 发起调用
Response response = handler1.handlerMessage(new Request()) ;
}

以上伪码显示责任链模式基本代码实现,然后实际会依据情况有很多变化。如每个链条只处理部分数据并交由后链条执行,直至责任链的终止,甚至可以没有任何返回结果,接下来小节将展示一个自动组装的责任链demo。

2、实现代码(Talk is cheap,Show me the code)

根据责任链模式设计细想,在服务提供的前置增加一个责任链,以完成参数校验、签名、日志、监控、追踪等通用的任务。对于客户端完全透明,对于服务端利用JAVA SPI机制(DUBBO SPI思想)灵活组装配置责任链,而如果结合上强大的spring Bean容器,很容易完成服务框架的定制工作。

下面demo示例:

  • Chain: 基本责任链中的链条定义
  • ChainHandler:负责责任链的组装和调用逻辑
  • ChainLoader:利用JAVA SPI机制,加载具体责任链实现
 public interface Process<T> {
T doProcess() ;
}

Process.java

 package com.nancy.chain.auto;

 public interface Chain {
int HIGHEST_ORDER = Integer.MIN_VALUE ;
int LOWEREST_ORDER = Integer.MAX_VALUE ; /**
* 处理逻辑
* @param chainHandler 责任链组装
* @param pos 下一个触发下标
* @param process 实际处理逻辑
* @return T 返回结果
*/
<T> T doChain(ChainHandler chainHandler, int pos, Process<T> process) ; /**
* 配置等级 越高优先级(越小) 越优先触发
* @param
* @return
*/
default Integer getOrder() {
return HIGHEST_ORDER ;
} }

Chain.java

 public abstract class AbstractChain implements Chain, Cloneable {

 }

AbstractChain.java

 public class ChainHandler extends AbstractChain {

     private List<Chain> chains ;

     public ChainHandler(List<Chain> chains){
this.chains = chains ;
chains.sort(Comparator.comparingInt(Chain::getOrder));
} private boolean hasNext(int pos){
return chains.size()-1 >= pos ;
} public List<Chain> getChains() {
return chains;
} public void setChains(List<Chain> chains) {
this.chains = chains;
} @Override
public <T> T doChain(ChainHandler chainHandler, int pos, Process<T> process) {
if(hasNext(pos)) return chainHandler.getChains().get(pos).doChain(chainHandler, ++pos, process);
return process.doProcess();
}
}

ChainHandler.java

 public class ChainLoader {

     public static List<Chain> loadChain(){
List<Chain> chains = new ArrayList<>() ;
ServiceLoader<Chain> serviceLoader = ServiceLoader.load(Chain.class);
serviceLoader.forEach(chains::add);
return chains ;
}
}

ChainLoader.java

 package com.nancy.chain.auto.impl;

 import com.nancy.chain.auto.AbstractChain;
import com.nancy.chain.auto.Chain;
import com.nancy.chain.auto.ChainHandler;
import com.nancy.chain.auto.Process;
import java.util.List; public class HelloChain extends AbstractChain { @Override
public <T> T doChain(ChainHandler chainHandler, int pos, Process<T> process) {
System.out.println("HelloChain被触发了");
return chainHandler.doChain(chainHandler, pos, process);
} @Override
public Integer getOrder() {
return LOWEREST_ORDER-1 ;
} } package com.nancy.chain.auto.impl;
import com.nancy.chain.auto.AbstractChain;
import com.nancy.chain.auto.ChainHandler;
import com.nancy.chain.auto.Process; public class LogChain extends AbstractChain { @Override
public <T> T doChain(ChainHandler chainHandler, int pos, Process<T> process) {
System.out.println("LogChain被触发了");
return chainHandler.doChain(chainHandler, pos, process);
} @Override
public Integer getOrder() {
return LOWEREST_ORDER ;
} }

链条

JAVA SPI机制中的文件: META-INF/services/

com.nancy.chain.auto.impl.HelloChain
com.nancy.chain.auto.impl.LogChain

触发责任链:

package com.nancy.chain.auto;
import com.nancy.chain.auto.spi.ChainLoader;
import java.util.List;
public class Main {
public static void main(String[] args) {
// 加载实现类
List<Chain> chains = ChainLoader.loadChain() ; // 触发
ChainHandler handler = new ChainHandler(chains) ;
Object res = handler.doChain(handler, 0, (Process<Object>) () -> 100) ; // 结果
System.out.println("结果" + res);
}
}

结果:

HelloChain被触发了
LogChain被触发了
结果100

3、注意点

  • 责任链模式会依据情况有很多变化。可以只由某个“链条”处理请求,或者每个链条只处理部分数据并交由后链条执行,直至责任链的终止。可以有结果返回或者没有任何返回结果。
  • 责任链模式可以解耦客户端和服务端,方便进行逻辑叠加。与观察者模式最大不同在于前者观察者是相互对等,之间没有影响。而后者由链条串联成线,链条之间可以建立起逻辑关系,完成某个功能。
  • 责任链模式当“链条”很长的时候会存在很大性能问题,设计之初应该考虑长度问题,长度限制在一定范围内。 而责任链之间大多具有逻辑关系,不适用类似观察者模式用异步线程处理的方式。
 
 
 
 
 
 
 
 
 
 
 
 
触发责任链:
[Chùfā zérèn liàn:]
Trigger chain of responsibility:
 
 
 
 
 
 
 
 
 
 
Prototype原型模式
[Prototype yuánxíng móshì]
Prototype prototype model
 
 
 
 

java设计模式解析(11) Chain责任链模式的更多相关文章

  1. Java设计模式(14)责任链模式(Chain of Responsibility模式)

    Chain of Responsibility定义:Chain of Responsibility(CoR) 是用一系列类(classes)试图处理一个请求request,这些类之间是一个松散的耦合, ...

  2. Java设计模式(九)责任链模式 命令模式

    (十七)责任链模式 责任链模式的目的是通过给予多个对象处理请求的机会,已解除请求发送者与接受者之间的耦合关系.面对对象的开发力求对象之前保持松散耦合,确保对象各自的责任最小化.这种设计能够使得系统更加 ...

  3. java设计模式(五)责任链模式

    很多对象有每个对象对其下家的引用而连接起来形成一条链,请求在这条链上传递,直到链上某个对象决定处理此请求,应用场景如单位审批流程等. 要点:1)抽象处理者角色:定义处理请求接口及设定下家引用    2 ...

  4. php设计模式课程---5、责任链模式是什么

    php设计模式课程---5.责任链模式是什么 一.总结 一句话总结: 自己权限不够,就交给上级处理 1.选择结构怎么做到面向对象开闭原则? 也就是说if,都可以用接口的实现来实现,这样就避免了更新的时 ...

  5. 【设计模式 - 13】之责任链模式(Chain Of Responsibility)

    1      模式简介 责任链模式的简介: 1.        责任链模式为请求创建了一个接收者对象的链,每个接收者都包含对另一个接收者的引用,如果一个对象不能处理该请求,那么它会把相同的请求传给下一 ...

  6. 浅谈Java五大设计原则之责任链模式

    首先我们得先定义一个责任链模式: 责任链模式是一种线性执行流程,多个对象都有机会去执行同一个任务,只是在执行过程中, 由于执行的权利和范围不一样,那么当自己不能处理此任务时,就必须将这个任务抛给下一个 ...

  7. 设计模式-(15)责任链模式 (swift版)

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

  8. 设计模式Design Pattern(3) -- 责任链模式

    什么是责任链模式? 责任链模式(Chain of Responsibility Pattern):请求知道公开接口,但不知道那个具体类处理,这些具体处理类对象连接成一条链.请求沿着这条链传递,直到有对 ...

  9. java23种设计模式之十:责任链模式

    最近在学习netty中发现其中用到了责任链模式,然后结合自己在写代码中遇到了大量写if...else的情况,决定学习一下责任链模式. 一.什么样的场景下会选择用责任链模式 我们在进行业务逻辑判断时,需 ...

随机推荐

  1. leetocode 207 课程表

    解题思路: 本题可约化为:课程安排图是否是 有向无环图(DAG).即课程间规定了前置条件,但不能构成任何环路,否则课程前置条件将不成立. 思路是通过 拓扑排序 判断此课程安排图是否是 有向无环图(DA ...

  2. Linux Ubntu 常用命令

    1.  ctrl+alt+t  打开一个终端命令窗口. 2.  在一个文件夹下 按ctrl+H,会显示以. 开头的文件. 3.  同时打开多个文件夹浏览窗口:在文件夹窗口中 Ctrl + N 4.  ...

  3. Windows连接已有界面的Ubuntu Linux

    Windows连接已有界面的Ubuntu Linux xrdp方式windows 10连接ubuntu 18.04 LTS 1. Ubuntu设置 Ubuntu的设置->Sharing项修改为下 ...

  4. dubbo学习之路-SPI机制

    dubbo学习之路-SPI机制 1.SPI 1.1Java SPI 原理 SPI是service provider interface简称.在java JDK中 内置的一种服务提供发现机制.它解决在一 ...

  5. python学习-63 组合

    组合 1.什么是组合? 定义一个类,由数据属性构成,这几个属性又可以是通过一个类实例化的对象,这就是组合. 举例: class School: def __init__(self,name,addre ...

  6. warning: LF will be replaced by CRLF in application.yml. The file will have its origina解决方法

    环境: windows提交时报错如图所示: 原因是存在符号转义问题 windows中的换行符为 CRLF, 而在linux下的换行符为LF,所以在执行add . 时出现提示,解决办法: git con ...

  7. Relative Sort Array

    Relative Sort Array Given two arrays arr1 and arr2, the elements of arr2 are distinct, and all eleme ...

  8. 转 Json数据格式化

    /// <summary> /// JSON字符串格式化 /// </summary> /// <param name="json"></ ...

  9. cxx11emu.h 和 logprint.h

    cxx11emu.h 和 logprint.h /* Start of cxx11emu.h */ #ifndef STDBP_CXX11EMU_H_ #define STDBP_CXX11EMU_H ...

  10. Java知识回顾 (11) 异常处理

    距离最近的 Java知识回顾系列(10),2019.4.24日,到现在,已经近半年过去了. 感觉,做一件事情,如果有头无尾,实在不好,心里会一直悬着.所以,现在继续上面的内容. 再次声明,正如(1)中 ...