- 浏览: 114734 次
- 性别:
- 来自: 武汉
文章分类
- 全部博客 (98)
- java (27)
- jms (2)
- jta (0)
- 性能调优及内存分析 (4)
- 设计模式 (14)
- 框架 (6)
- 其它 (9)
- job (1)
- maven (1)
- 服务器 (2)
- 分布式 (3)
- ibatis (1)
- linux (0)
- mysql (0)
- 并发编程 (0)
- java多线程 (2)
- 前端跨域 (1)
- 线程dump分析 (0)
- velocity (0)
- 数据库 (2)
- 协议 (0)
- 监控 (0)
- 开源软件 (2)
- 算法 (0)
- 网络 (1)
- spring (1)
- 编码 (0)
- 数据结构 (0)
- HTable和HTablePool使用注意事项 (0)
- opencms (0)
- android (16)
- 操作系统 (2)
- top (0)
最新评论
-
hold_on:
@Override public boolea ...
android listview的HeadView左右切换图片(仿新浪,网易,百度等切换图片) -
achersnake:
123
Servlet中listener(监听器)和filter的总结 -
angel243fly:
我用了这个方法,还是报同样的错误,还有什么建议吗?
eclipse提示CreateProcess error=87错误的解决方法
转:http://haolloyin.blog.51cto.com/1177454/348277
之前在 benjielin 前辈的博客中看到“管道过滤器(Pipe-And-Filter)模式( http://bj007.blog.51cto.com/1701577/345677 )”,当时将文章中运用到的组合模式(Composite)与我刚刚写过的装饰模式(Decorator)和职责链模式(Chain of Responsibility)混为一谈,并希望用这后面两个模式进行代码实现,+_+
现在觉得还是先把那文章中的组合模式给具体实现一下吧,具体的文字描述请看上面文章链接哦。
在我的代码中,我假设的需求是:给定多个条件(即过滤器),遍历一本字典中的所有单词,将同时符合所有条件 的所有单词查询(过滤)出来。现假定需要过滤出“单词中同时包含a、b、cd字串,并且以"end”结尾,最后是单词的长度大于7 ”。
好了,看清了需求,得出类图如下:
- // 字典
- class Dictionary {
- // 字典里面有好多单词
- private ArrayList<String> allWords;
- public Dictionary(ArrayList<String> allWords) {
- this .allWords = allWords;
- }
- // 获取字典中所有单词
- public ArrayList<String> getAllWords() {
- return this .allWords;
- }
- }
- // 过滤器接口,只有 match() 方法
- interface IFilter {
- public boolean match(String word);
- }
- // 树叶型 过滤器,过滤单词中长度大于指定长度
- class LengthFilter implements IFilter {
- private int length;
- public LengthFilter(int length) {
- this .length = length;
- }
- @Override
- public boolean match(String word) {
- if (word.length() > length) {
- return true ;
- }
- return false ;
- }
- }
- // 树叶型 过滤器,过滤单词中包含有某个字符字串
- class ContainsFilter implements IFilter {
- private String subStr;
- public ContainsFilter(String subStr) {
- this .subStr = subStr;
- }
- @Override
- public boolean match(String word) {
- if (word.contains (subStr)) {
- return true ;
- }
- return false ;
- }
- }
- // 树叶型 过滤器,过滤单词中以某个字符字串结束
- class EndFilter implements IFilter {
- private String subStr;
- public EndFilter(String subStr) {
- this .subStr = subStr;
- }
- @Override
- public boolean match(String word) {
- if (word.endsWith (subStr)) {
- return true ;
- }
- return false ;
- }
- }
- // 抽象组合型 过滤器,类似于树枝节点
- abstract class CompositeFilter implements IFilter {
- protected ArrayList<IFilter > filters;
- public CompositeFilter() {
- this .filters = new ArrayList<IFilter>();
- }
- // 继续将 IFilter 接口中的 match() 声明为 abstract,
- // 由具体的过滤器子类进行实现
- public abstract boolean match(String word);
- // 添加过滤器链
- public void addFilters(ArrayList<IFilter > filters) {
- this .filters.addAll(filters);
- }
- // 添加一个过滤器
- public void addFilter(IFilter filter) {
- this .filters.add(filter);
- }
- // 既然是树枝过滤器,其下必有子过滤器
- public ArrayList<IFilter> getFilters() {
- return this .filters;
- }
- }
- // and 过滤器,树枝型 过滤器
- class AndFilter extends CompositeFilter {
- @Override
- public boolean match(String word) {
- for (IFilter filter : super .filters) {
- if (!(filter.match(word))) {
- return false ;
- }
- }
- return true ;
- }
- }
- // or 过滤器,树枝型 过滤器
- class OrFilter extends CompositeFilter {
- @Override
- public boolean match(String word) {
- for (IFilter filter : super .filters) {
- if (filter.match(word)) {
- return true ;
- }
- }
- return false ;
- }
- }
- // 管道
- class Pipe {
- // 字典,相当于流入管道的数据流
- private Dictionary dictionary;
- // 用于保存过滤后的最终数据
- private LinkedHashSet<String> theWords;
- // 单词查询中需要用到的过滤器树
- private IFilter filterTree;
- // 用于保存字典中的所有单词,即数据流中的一个个数据
- private ArrayList<String> allWords;
- public Pipe(Dictionary dictionary, IFilter filterTree) {
- this .dictionary = dictionary;
- this .filterTree = filterTree;
- this .theWords = new LinkedHashSet<String>();
- }
- public LinkedHashSet<String> getWords() {
- // 先搜索过滤字典中所有单词,再返回符合要求的单词集合
- this .allWords = dictionary.getAllWords();
- this .findWords();
- return this .theWords;
- }
- private void findWords() {
- // 对每个单词进行过滤
- for (String word : allWords) {
- if (filterTree.match(word) == true ) {
- this .theWords.add(word);
- }
- }
- }
- }
- // 测试类
- public class Client {
- public static void main(String[] args) {
- // 创建过滤器树: 包含"a"、"b"、"cd"子串,以"end"结尾,长度 > 7
- // 同时包含"a"、"b"、"cd"子串的过滤器
- CompositeFilter andFilter = new AndFilter();
- IFilter contain01 = new ContainsFilter("a" );
- IFilter contain02 = new ContainsFilter("b" );
- IFilter contain03 = new ContainsFilter("cd" );
- andFilter.addFilter(contain01);
- andFilter.addFilter(contain02);
- andFilter.addFilter(contain03);
- // 以 "end" 或 "END" 结尾的过滤器
- CompositeFilter orFilter = new OrFilter();
- IFilter end01 = new EndFilter("end" );
- IFilter end02 = new EndFilter("END" );
- orFilter.addFilter(end01);
- orFilter.addFilter(end02);
- // 长度 > 7 的过滤器
- IFilter lengthFilter = new LengthFilter(7 );
- // 构建过滤器树,用根过滤器 将上面的所有过滤器组合起来
- CompositeFilter rootFilter = new AndFilter ();
- rootFilter.addFilter(andFilter);
- rootFilter.addFilter(orFilter);
- rootFilter.addFilter(lengthFilter);
- // 自定义一本字典里的所有单词
- ArrayList<String> allWords = new ArrayList<String>();
- allWords.add("akkkk" );
- allWords.add("ab--b-cd--end" );
- allWords.add("abckk" );
- allWords.add("abdcend" );// 长度为6,不符合
- allWords.add("kakbkck" );
- allWords.add("a-b-cd-END" );
- allWords.add("bbcc" );
- // 自定义一本字典
- Dictionary dictionary = new Dictionary(allWords);
- // 将字典、过滤器树传入管道
- Pipe pipe = new Pipe(dictionary, rootFilter );
- // 单词流在通过管道时被过滤,获取最终单词
- System.out.println(pipe.getWords());
- }
- }
测试结果:
- [ab--b-cd--end, a-b-cd-END]
如此一来,基本上解决了我在原来文章中的许多疑问(下面的是修改前的内容),根据 benjielin 前辈的提示,修改了原来完全不合理的地方,可看评论哦。
话说回来,原来的代码也太乱了,原因就是我完全理解错了 benjielin 前辈文章中关于组合模式中AndFilter 类、OrFilter 类的用处,也完全没弄明白组合模式究竟用于何处,呼...
小结:
1、Pipe 类中过滤的代码少了很多,只是调用过滤器的 match() 方法而已;
2、由 1 也相应地去除了由 Pipe 类来判断对象属于树叶还是树枝类型的逻辑,消去了坏味道;
3、原文中利用递归遍历过滤器树的方法一点都不合理,完全应该去除,当初是因为没理清思路;
4、改变主意,不用 职责链模式 来实现 管道过滤器模式了,因为现在我觉得那个模式应该实现不了 Composite 模式这样的功能,它最多也只能起到 链 的作用。
我的相关文章:
组合模式(Composite)的安全模式与透明模式 http://haolloyin.blog.51cto.com/1177454/347308
职责链模式(Chain of Responsibility)的Java实现 http://haolloyin.blog.51cto.com/1177454/342166
以下是修改前的部分内容,可不看,因为太不合理了。但我还是想保存着,毕竟是从以下代码修改而来的,所以可以参看benjielin前辈的评论来看。
类图如下:
代码如下:
//树叶型
过滤器,直接实现 IFilter ,过滤单词中长度大于 7
class
LengthFilter implements
IFilter {
@Override
public
boolean
match(String word) {
if
(word.length() > 7) {
return
true
;
}
return
false
;
}
}
// 抽象组合型过滤器,类似于树枝
节点
abstract
class
CompositeFilter implements
IFilter {
private
ArrayList<IFilter> filters;
// 需要被过滤的单词中的字串
protected
String subStr;
public
CompositeFilter(String subStr) {
this
.filters = new
ArrayList<IFilter>();
this
.subStr = subStr;
}
// 继续将 IFilter 接口中的 match() 声明为 abstract
,
// 由具体的过滤器子类进行实现
public
abstract
boolean
match(String word);
// 添加过滤器链
public
void
addFilters(ArrayList<CompositeFilter> filters) {
this
.filters.addAll(filters);
}
// 添加一个过滤器
public
void
addFilter(IFilter filter) {
this
.filters.add(filter);
}
public
ArrayList<IFilter> getNextFilter() {
return
this
.filters;
}
}
// 过滤单词中包含有某个字符子串
的组合型过滤器
class
ContainsFilter extends
CompositeFilter {
public
ContainsFilter(String subStr) {
super
(subStr);
}
@Override
public
boolean
match(String word) {
if
(word.contains(super
.subStr)) {
return
true
;
}
return
false
;
}
}
// 过滤单词中以某个字符字串结束
的组合型过滤器
class
EndFilter extends
CompositeFilter {
public
EndFilter(String subStr) {
super
(subStr);
}
@Override
public
boolean
match(String word) {
if
(word.endsWith(super
.subStr)) {
return
true
;
}
return
false
;
}
}
// 管道
class
Pipe {
// 字典,相当于流入管道的数据流
private
Dictionary dictionary;
// 用于保存过滤后的最终数据
private
LinkedHashSet<String> theWords;
// 单词查询中需要用到的过滤器树
private
CompositeFilter filterTree;
// 用于保存字典中的所有单词,即数据流中的一个个数据
private
ArrayList<String> allWords;
public
Pipe(Dictionary dictionary, CompositeFilter filterTree) {
this
.dictionary = dictionary;
this
.filterTree = filterTree;
this
.theWords = new
LinkedHashSet<String>();
}
public
LinkedHashSet<String> getWords() {
// 先搜索过滤字典中所有单词,再返回符合要求的单词集合
this
.allWords = dictionary.getAllWords();
this
.findWords();
return
this
.theWords;
}
private
void
findWords() {
// 对每个单词进行过滤
for
(String word : allWords) {
if
(doFilter(word, filterTree) == true
) {
this
.theWords.add(word);
}
}
}
// 递归遍历过滤器树
private
boolean
doFilter(String word, CompositeFilter filterTree) {
ArrayList<IFilter> filters = filterTree.getNextFilter();
// 标志位,若为 true 则说明该单词符合条件
boolean
flag = true
;
for
(IFilter filter : filters) {
if
(!filter.match(word)) {
flag = false
;
break
;
}
// 若是组合型过滤器,即树枝,则递归过滤
if
(filter instanceof
CompositeFilter) {
CompositeFilter thisFilter = (CompositeFilter) filter;
doFilter(word, thisFilter);
}
}
return
flag;
}
}
// 测试类
public
class
Client {
public
static
void
main(String[] args) {
// 创建过滤器: 包含"a"、"b"、"cd"子串,以"end"结尾,长度 > 7
// 包含"a"、"b"、"cd"子串的过滤器
CompositeFilter filter01 = new
ContainsFilter("a
");
CompositeFilter filter02 = new
ContainsFilter("b
");
CompositeFilter filter03 = new
ContainsFilter("cd
");
// 以"end"结尾的过滤器
CompositeFilter endFilter = new
EndFilter("end
");
// 长度 > 7 的过滤器
IFilter lengthFilter = new
LengthFilter();
// 构建过滤器树
filter01.addFilter(filter02);
filter01.addFilter(filter03);
filter01.addFilter(endFilter);
filter01.addFilter(lengthFilter);
// 自定义一本字典里的所有单词
ArrayList<String> allWords = new
ArrayList<String>();
allWords.add("akkkk
");
allWords.add("abkkbkcdend
");
allWords.add("abckk
");
allWords.add("abdcend
"); //长度为6,不符合
allWords.add("kakbkck
");
allWords.add("kkkkkk
");
allWords.add("bbcc
");
// 自定义一本字典
Dictionary dictionary = new
Dictionary(allWords);
// 将字典、过滤器树传入管道
Pipe pipe = new
Pipe(dictionary, filter01);
// 单词流在通过管道时被过滤,获取最终单词
System.out.println(pipe.getWords());
}
}
测试结果:
[abkkbkcdend]
呼…代码太长了,总算是写出来了,从字典中过滤出我们需要的单词了。但是,面对这样的结构,我有如下疑问:
1、上面在 Client 类中并没有“真正”使用到组合模式,它不是一棵过滤器树 充其量也只是作为一条过滤器链 而已,没有体现出组合模式那种“层次”,即一个中间过滤器下面还一棵树,在 Client 类中构建过滤器树时其实是一个根节点 filter01 下面链接着其他4个过滤器对象;所以,在代码中的 Pipe 类中进行递归过滤时用得并不实际;
2、我在想,管道过滤器模式中是不是一定要用到组合模式来体现出具有层次之别的过滤器族?如果不是的话,那么用职责链模式 来实现我上面的效果我认为会更加便利、快速(接下来我会尝试实现一下),因为在这里体现不出 组合模式(Composite)强调的“整体-部分 ”的特性(也很有可能是我理解不到位);
3、其实,上面实现的过滤 String 变量可以直接用正则表达式实现,那样子更更更简单,由此不免感叹一下:正则表达式太强大了 ;
本文出自 “蚂蚁 ” 博客,请务必保留此出处http://haolloyin.blog.51cto.com/1177454/348277
发表评论
-
装饰模式和代理模式的区别
2012-04-05 14:00 794从功能效果上看 装饰模式:在不改变接口的前提下,动态扩展 ... -
组合模式
2012-04-05 10:58 571转:http://blog.csdn.net/ai92/art ... -
观察者模式
2012-03-31 16:51 703转:http://lavasoft.blog.51ct ... -
责任链模式
2011-10-21 09:25 921责任链模式(Chain of Responsibility P ... -
门面模式
2011-10-21 08:47 923转:http://daimajishu.iteye.com ... -
Builder生成器模式
2011-04-14 11:03 768转:http://www.jdon.com/designpat ... -
原型模式
2011-04-14 10:36 747转:http://www.impeng.org/pro ... -
单例模式
2011-04-14 10:09 701转:http://tianli.blog.51cto.co ... -
模板模式
2011-04-13 10:59 805转:http://tianli.blog.51cto.com/ ... -
工厂模式
2011-04-13 10:46 691简单工厂模式 1. 目的 工厂模式就是专 ... -
适配器模式
2011-04-13 10:24 667转:http://lavasoft.blog.51ct ... -
迭代器模式
2011-04-13 10:09 919转:http://tianli.blog.51cto. ... -
装饰器模式[Decorator]
2011-04-06 12:19 687:http://hi.baidu.com/fortin10 ...
相关推荐
管道过滤器(Pipe and Filter)模式是一种经典的软件设计模式,它在Java和其他许多编程语言中广泛应用,尤其是在处理数据流和事件处理系统中。这个模式的主要思想是将复杂的处理任务分解成一系列可重用的过滤器组件...
这个"pipecodefiltter.zip"压缩包包含了一系列与管道过滤器相关的Java源代码文件,如Alphabetizer11.java、KWIC11.java、Input11.java、CircularShifter11.java、Pipe11.java、Filter11.java以及Output11.java,这些...
管道过滤器运行中的pipe-filter pattern 。样本给定一个字符串列表,找到所有包含a , b和c字符的字符串。 // A list of string...stringList = Pipe . in(stringList) . then(data - > data . stream() . filter...
在这个程序示例中,我们看到的是利用管道-过滤器(Pipe-Filter)设计模式来实现的。这种模式在处理大量数据流时特别有用,因为它允许将复杂任务分解为一系列简单的、可重用的组件。 管道-过滤器模式的核心思想是将...
- **EJB/JBoss:** 在EJB容器中,管道过滤模式主要体现在容器与远程客户端之间的通信过程中。例如,EJB容器接收远程调用,并对其进行分析以提供相应的管理服务。EJB容器的底层通信模型可以视为多个过滤器和管道的...
在IT行业中,"CalculatricePipeAndFilter_java_pipeline_"这一标题暗示了一个使用Java实现的计算器应用,它采用了管道和过滤器(Pipe and Filter)设计模式。这个设计模式是一种常见于处理流水线系统的架构,尤其...
其中,"管道过滤器"(Pipe Filter)模式是一种设计模式,常用于处理大量数据流的应用程序,如文本处理、数据过滤和转换等。在处理千年虫问题时,这种模式可能被用来高效地分发、转换和验证数据,确保每个阶段都能...
本项目聚焦于一种特定的设计模式——管道过滤器模式(Pipe-Filter Pattern),通过一系列组件对数据进行处理,最终达到预期的目标。本项目的主要目标是通过对一个具体实例的学习和实践,理解并掌握该设计模式的基本...
2. 管道模式(Pipe and Filter):将复杂的任务分解为一系列相互连接的过滤器,每个过滤器在一个独立的线程中运行,提高了系统处理能力。Java的java.util.stream.Stream API可以实现类似的功能。 3. 线程池模式:...
数据流风格是软件体系结构风格的一种,管道/过滤器结构拥有一组被称为过滤器(filter)的构件,这些构件通过管道(pipe)连接,管道将数据从一个构件传送到下一个构件。每个过滤器独立于其上游和下游的构件而工作,...
4. 管道和过滤器(pipe and filter)实现:可能是一系列处理文本的脚本或程序,按照管道模型进行连接,例如,一个程序读取输入文本,下一个程序提取关键词,再下一个程序构建KWIC格式输出。 5. 示例数据:可能包含...
这是管道过滤器(P&F)框架的C ++实现。 它基于的,但是已经通过多种方式适应了C ++,以支持现代C ++程序所依赖的所有语言功能。 它为P&F体系结构的建模和执行提供支持。 特征 开发和连接阶段的一种类型安全的方式...
5. **管道与过滤器(Pipe and Filter)**:面向数据流编程,通过一系列相互连接的过滤器,每个过滤器处理数据的一个方面,最终形成完整的结果。这种模式在企业集成中广泛应用。 6. **映射与归约(MapReduce)**:Google...
`@Pipe`装饰器内有一个对象,包含了管道的名字`name: 'filterUser'`。这个类需要实现`PipeTransform`接口,因此我们需要定义一个`transform`方法,这个方法接收输入值(allUsers)和可选参数(args),并返回处理后...
常见的软件架构风格有层次式架构(Layered Architecture)、客户端-服务器架构(Client-Server)、微服务架构(Microservices)、事件驱动架构(Event-Driven)、管道和过滤器架构(Pipe and Filter)等。...
本篇将详细探讨"evolution-message-filter",这是一种与Evolution消息过滤器相关的技术,特别是其"管道到程序"(pipe-to-program)条件的使用。 "管道到程序"是Evolution过滤器中的一个高级特性,它允许用户通过...
使用rlwrap的-z选项调用过滤器: rlwrap -z "<FILTER>" <OTHER> 如果要使用多个过滤器,则可以使用rlwrap -z "<FILTER>" <OTHER> 随附的pipeline过滤器,如下所示: rlwrap -z 'pipeline <FILTER1>:<FILTER2>:<ETC>'...
而管道-过滤器架构中,组件(filter)独立,通过连接器(pipe)传递数据,且处理顺序不影响结果的正确性。 8. 管道-过滤器架构特点与优缺点: - 优点:支持组件重用,组件独立,无共享状态,易于扩展和维护。 - ...
在 Haskell 中,管道通常用于实现过滤、转换、组合等操作,将数据流通过一系列处理步骤。`simple-pipe` 库利用了 Haskell 的高阶函数和类型系统,使得构建复杂的管道变得非常直观。它定义了一种名为 `Pipe` 的类型,...