管道模式——pipeline与valve
在一个比较复杂的大型系统中,假如存在某个对象或数据流需要被进行繁杂的逻辑处理的话,我们可以选择在一个大的组件中进行这些繁杂的逻辑处理,这种方式确实达到了目的,但却是简单粗暴的。或许在某些情况这种简单粗暴的方式将带来一些麻烦,例如我要改动其中某部分处理逻辑、我要添加一些处理逻辑到流程、我要在流程中减少一些处理逻辑时,这里有些看似简单的改动都让我们无从下手,除了对整个组件进行改动。整个系统看起来没有任何可扩展性和可重用性。
是否有一种模式可以将整个处理流程进行详细划分,划分出的每个小模块互相独立且各自负责一段逻辑处理,这些逻辑处理小模块根据顺序连起来,前以模块的输出作为后一模块的输入,最后一个模块的输出为最终的处理结果。如此一来修改逻辑时只针对某个模块修改,添加或减少处理逻辑也可细化到某个模块颗粒度,并且每个模块可重复利用,可重用性大大增强。这种模式就是此章节要进行讨论的管道模式。
顾名思义,管道模式就像一条管道把多个对象连接起来,整体看起来就像若干个阀门嵌套在管道中,而处理逻辑就放在阀门上,如下图,需要处理的对象进入管道后,分别经过阀门一、阀门二、阀门三、阀门四,每个阀门都会对进入的对象进行一些逻辑处理,经过一层层的处理后从管道尾处理,此时的对象就是已完成处理的目标对象。
既然管道模式这么有用,我们希望能在程序中适当地考虑使用,为了实现此模式需要多个对象协作,可参考如下类图,Valve接口定义了阀门的调用方法,由于阀门与阀门使用单链表结构连接所以需提供对next的操作,实现一个阀门对其进行扩展即可;Pipeline接口定义了管道操作阀门的方法,包括获取第一个阀门、获取基础阀门、添加阀门等方法,管道需对其扩展。
往下看如何简单实现一个管道模式:
① 阀门接口
public interface Valve {
public Valve getNext();
public void setNext(Valve valve);
public void invoke(String handling);
}
② 管道接口
public interface Pipeline {
public Valve getFirst();
public Valve getBasic();
public void setBasic(Valve valve);
public void addValve(Valve valve);
}
③ 基础阀门,处理逻辑仅仅是简单的将传入的字符串中”aa”替换成”bb”
public class BasicValve implements Valve {
protected Valve next = null;
public Valve getNext() {
return next;
}
public void invoke(String handling) {
handling=handling.replaceAll("aa", "bb");
System.out.println("基础阀门处理完后:" + handling);
}
public void setNext(Valve valve) {
this.next = valve;
}
}
④ 第二个阀门,将传入的字符串中”11”替换成”22”
public class SecondValve implements Valve {
protected Valve next = null;
public Valve getNext() {
return next;
}
public void invoke(String handling) {
handling = handling.replaceAll("11", "22");
System.out.println("Second阀门处理完后:" + handling);
getNext().invoke(handling);
}
public void setNext(Valve valve) {
this.next = valve;
}
}
⑤ 第三个阀门,将传入的字符串中”zz”替换成”yy”
public class ThirdValve implements Valve {
protected Valve next = null;
public Valve getNext() {
return next;
}
public void invoke(String handling) {
handling = handling.replaceAll("zz", "yy");
System.out.println("Third阀门处理完后:" + handling);
getNext().invoke(handling);
}
public void setNext(Valve valve) {
this.next = valve;
}
}
⑥ 管道,我们一般的操作是先通过setBasic设置基础阀门,接着按顺序添加其他阀门,执行时的顺序是:先添加进来的先执行,最后才执行基础阀门。
public class StandardPipeline implements Pipeline {
protected Valve first = null;
protected Valve basic = null;
public void addValve(Valve valve) {
if (first == null) {
first = valve;
valve.setNext(basic);
} else {
Valve current = first;
while (current != null) {
if (current.getNext() == basic) {
current.setNext(valve);
valve.setNext(basic);
break;
}
current = current.getNext();
}
}
}
public Valve getBasic() {
return basic;
}
public Valve getFirst() {
return first;
}
public void setBasic(Valve valve) {
this.basic = valve;
}
}
⑦ 测试类
public class Main {
public static void main(String[] args) {
String handling="aabb1122zzyy";
StandardPipeline pipeline = new StandardPipeline();
BasicValve basicValve = new BasicValve();
SecondValve secondValve = new SecondValve();
ThirdValve thirdValve = new ThirdValve();
pipeline.setBasic(basicValve);
pipeline.addValve(secondValve);
pipeline.addValve(thirdValve);
pipeline.getFirst().invoke(handling);
}
}
输出的结果如下:
Second阀门处理完后:aabb2222zzyy
Third阀门处理完后:aabb2222yyyy
基础阀门处理完后:bbbb2222yyyy
这就是管道模式,在管道中连接一个或多个阀门,每个阀门负责一部分逻辑处理,数据按规定的顺序往下流。此模式分解了逻辑处理任务,可方便对某任务单元进行安装拆卸,提高了流程的可扩展性、可重用性、机动性、灵活性。
喜欢研究java的同学可以交个朋友,下面是本人的微信号:
管道模式——pipeline与valve的更多相关文章
- laravel5.5源码笔记(五、Pipeline管道模式)
Pipeline管道模式,也有人叫它装饰模式.应该说管道是装饰模式的一个变种,虽然思想都是一样的,但这个是闭包的版本,实现方式与传统装饰模式也不太一样.在laravel的源码中算是一个比较核心的设计模 ...
- Tomcat源码分析 (四)----- Pipeline和Valve
在 Tomcat源码分析 (二)----- Tomcat整体架构及组件 中我们简单分析了一下Pipeline和Valve,并给出了整体的结构图.而这一节,我们将详细分析Tomcat里面的源码. Val ...
- Redis学习笔记7--Redis管道(pipeline)
redis是一个cs模式的tcp server,使用和http类似的请求响应协议.一个client可以通过一个socket连接发起多个请求命令.每个请求命令发出后client通常会阻塞并等待redis ...
- 使用管道(PipeLine)和批量(Batch)操作
使用管道(PipeLine)和批量(Batch)操作 前段时间在做用户画像的时候,遇到了这样的一个问题,记录某一个商品的用户购买群,刚好这种需求就可以用到Redis中的Set,key作为product ...
- 浅谈管道模型(Pipeline)
本篇和大家谈谈一种通用的设计与处理模型--Pipeline(管道). Pipeline简单介绍 Pipeline模型最早被使用在Unix操作系统中.据称,假设说Unix是计算机文明中最伟大的发明,那么 ...
- .NET客户端实现Redis中的管道(PipeLine)与事物(Transactions)
序言 Redis中的管道(PipeLine)特性:简述一下就是,Redis如何从客户端一次发送多个命令,服务端到客户端如何一次性响应多个命令. Redis使用的是客户端-服务器模型和请求/响应协议的T ...
- Redis中的管道(PipeLine)与事物(Transactions)
Redis中的管道(PipeLine)与事物(Transactions) 序言 Redis中的管道(PipeLine)特性:简述一下就是,Redis如何从客户端一次发送多个命令,服务端到客户端如何一次 ...
- 【配置】检测到在集成的托管管道模式下不适用的ASP.NET设置的解决方法(非简单设置为【经典】模式)。
× 检测到在集成的托管管道模式下不适用的ASP.NET设置的解决方法(非简单设置为[经典]模式). 我们将ASP.NET程序从IIS6移植到IIS7,可能运行提示以下错误: HTTP 错误 5 ...
- VS下运行项目时,检测到在集成的托管管道模式下不适用的 ASP.NET 设置。
vs2012调试时默认会是集成模式,vs2012调试时怎么使用传统模式哪? 这个时候只要选中启动项目按F4,在托管管道模式里选传统模式即可!
随机推荐
- iphone inline video fragments
DOMContentLoaded 它在DOM加载之后及资源加载之前被触发 通过递归调用同一方法来不断更新画面以达到动起来的效果,但它优于setTimeout/setInterval的地方在于它是由浏览 ...
- 学习C语言第一天!
整理心得笔记: 1)c语言程序由函数构成,每个函数可以实现一个或多个功能. 2)一个正规程序可以有多个函数,但是有且只有一个主函数. 3)函数只有在被调用的时候才执行,主函数由系统调用执行. 4 ...
- ubuntu批量更改文件权限
重装系统之后,把文件从windows分区拷到linux分区发现所有文件的权限全是777,在终端下看到所有文件的颜色都很刺眼,文件有很多,一个一个改不现实,所以写了一段python脚本批量更改文件权限. ...
- CSS相关
===CSS框架=== https://github.com/lucasgruwez/waffle-grid 一个易于使用的 flexbox 栅格布局系统 ===CSS初始化=== https://g ...
- 剑指架构师系列-ftp服务器
1.安装FTP 我们在开发项目时,肯定需要专门的一台ftp服务器来存在上传的静态资源,今天我们就在CentOS下搭建一个ftp服务器. 1.安装vsftpd组件,安装完后,有/etc/vsftpd/v ...
- 2018 dnc 公司案例大全,迎接.NET Core开源新时代
2018 dnc 公司案例大全,迎接.NET Core开源新时代 dnc = .NET Core.dotnet Core dnc是微软新一代主力编程平台,开源.免费.跨平台.轻量级.高性能,支持L ...
- 从输入url到页面返回到底发生了什么
1. 前言 Google应该是开发者平日里用得最多的网站之一,今早笔者在浏览器地址栏里键入www.google.com的时候,突然想了解下这背后的网络通信过程究竟是怎么样的.毕竟自己也算是一名Web开 ...
- Oracle性能优化-读懂执行计划
Oracle的执行计划 得到执行计划的方式 Autotrace例子 使用Explain explain plan set STATEMENT_ID='testplan' for select * fr ...
- Docker学习笔记3:CentOS7下安装Docker-Compose
Docker-Compose是一个部署多个容器的简单但是非常必要的工具. 安装Docker-Compose之前,请先安装 python-pip,请参考我的另一篇博文CentOS7下安装python-p ...
- Android开发学习之路--逆向分析反编译
一般情况下我们想要了解别人的app怎么实现这个动画,这个效果的时候,总是会想到反编译一下,看下布局,看下代码实现.对,这对于有经验的玩家确实手到擒来了,但是初学者,根本就不知道怎么反编译,怎么看代 ...