从容应对变化——从一个简单搜索工具架构浅谈Java设计模式

2022-11-04

1 关于Java

Java语言本身并没有什么神秘的地方, 而我们之所以能感觉到Java的方便快捷, 很大程度上得益于原Sun公司为我们提供的完善的API封装。JDK本身就很好地体现了面向对象程序设计的各种元素, 同时还融入了各种“设计模式”的精华, 很值得我们借鉴和学习。本文就通过一个简易的文本搜索工具来浅显地探讨几个最为普通和常用的设计模式。这个小小的文本搜索引擎, 其重心不在于智能而高效的搜索算法, 而在于对“模式”的一次实战演练。该引擎基于Java JDK 1.6构建。该引擎的最初需求很简单, 用户键入要搜索的单词, 引擎返回所有包含该单词的文件列表。为方便起见, 这里暂时只涉及英文单词搜索。

为满足需求, 细节的设计架构由以下几部分构成。首先是索引建立, 采用反向页表方式, 每个单词为节点, 后跟所有包含该单词的文件引用。索引建立完成之后便是搜索, 其主要是集合操作, 不做赘述。上述是该搜索工具的主要架构, 主要有如下一些内容。

Tester:充当外部测试程序与该搜索工具的适配器, 提供两个public static方法可以直接通过类名引用, 并直接通过传递参数的方式使系统工作起来。

RUSE Interface:充当搜索工具的外部面板, 生成使系统工作的各个元素。它持有一个静态的RUSE Engine引用, 用来真正生成对象;然后有两个供Tester调用的静态方法。从而完成内部系统和外部系统的对接。

RUSE En gine:充当工程的工厂, 其所有职责就是生成对象。

Data S tructure I O:IO的工作, 负责文件从内存到磁盘的读写。

Snow Ball Stemmer:这是个第三方插件, 用来完成上文提到的单词形式的变化工作。

RUSE Invoker:充当遥控器角色, 持有一个命令, 从用户那儿获取指令并执行这个命令。

Index Creator:这是一个重要的接口, 提供归一化方法原型, 所有具体实现索引建立功能的模块都将实现该接口。该接口持有一个索引建立模块的对象引用, 但它并不关心该对象是怎么实现的。对于不同类型的索引当然有不同的实现方法, 但它们都有相同的本质, 可以将之抽象出来。

In de x St ru ct ur e:最根本的部分, 定义了索引数据存储的格式。JDK为我们提供了很多现成的接口比如Hash Map和Hash Set, 当然, 更有效的数据结构可以随时被定义并应用到该工具中来。

File Accessory:用来读取不同的文件类型。我们建立的工具显然不能只搜索文本文件, 对于其他的文件类型, 我们可以方便使用第三方插件来扩充。

Query Processor:用户搜索请求的中央处理器, 控制基本数据流。具体的搜索算法由Query Analyzer实现。

Query Analyze:处理用户的搜索请求, 它也是一个接口, 定义了一个算法的模板。

2 所用到的设计模式探讨

Strategy Pattern

策略模式是该工具中使用最广的一个模式, 它可以相当有效地封装某个模块需要和其他模块独立开来的部分。有一些必要的封装如下。

首先是用户。用户当然只需要知道要搜索的文件类型以及要搜索的单词, 以及在哪个目录下进行搜索。至于工具内部具体怎样实现, 普通用户不需要也不会关心这些。另一个是索引建立。反向页表是方法之一, 但决不是唯一, 其他方法当然也可以, 只要它们拥有类似的实现结构。

其他还有一些必要的封装, 如:字符串分析器获得用户输入, 并将其解释为搜索处理器可以识别的形式。搜索处理器能够处理的形式很简单, 无非是一些集合操作逻辑, 但这些逻辑的表现方式多种多样, 尤其从用户输入的字符串当中获取时更是如此。

Observer Pattern

具体使用到“观察者”模式的是文件读取模块。索引构造器需要读取各种不同的文件类型, 而这些文件类型可能是由用户指定的, 索引构造器事先并不知道。显然不同类型的文件, 读取方式也不一样, 文本文件和Word文档以及PDF文件各有其读取方式, 但在索引构造器看来, 其性质都一样。此时可以使用“观察者”模式, 降低程序和具体文件类型的耦合度。每种不同的文件读取模块按照需要动态地注册给索引构造器, 索引构造器在构建索引时遍历已注册的模块列表, 发号施令, 各个读取模块便各司其职, 读取自己所负责的文件, 并返回具有统一格式的字符流数据。

Factory Pattern

可以说, 凡是涉及到对象生成的功能都可以交给工厂去做。随便在需要对象实例的地方对对象进行初始化是不合适的。

Command Pattern

程序的主接口申请了各种命令以完成某种功能要求。在用户看来, 针对该搜索工具主要有两种命令:建立索引和搜索。这些命令从外部读取需要的参数, 然后交给相应的执行者执行。

Template Pattern

模板模式主要用在搜索处理器模块的搜索算法上。针对存储索引的数据结构的变化, 会有不同的算法加以应对, 而且即使是同样的数据结构, 算法本身也在变换, 以达到更高的效率和准确度。但站在高层的角度, 整个算法的流程是大致统一的, 可以将其归到相同算法模板的不同实例, 针对不同实际情况的不同选择。

Fa ade and Adapter Pattern

相对简单的设计模式, 但并不代表不重要。它将不同的接口之间进行适配和统一。这个搜索工具并不是一个具有完整功能的产品, 很可能会与外部的其他应用进行对接, 但总体的功能是不变的, 因此, 只需要在接口上将其适配到外部应用之上, 便可以保证系统的工作。

3 结语

当然, 模式不是一成不变, 已有的模式也远不止上面这几种。只要可以提高实际的生产效率, 任何时刻都可以定义属于自己的模式。作为任何一个使用Java进行开发的人员, 尝试理解并学习应用JDK中的模式思想有益而无弊。有关设计模式的话题可以延伸到一个图书室, 而这篇文章仅仅几千字, 所涉及的内容不及整个模式内涵的皮毛, 在此只是抛砖引玉, 引发读者对设计模式更深层次的思考。

摘要:随着社会发展对软件依赖程度的提高, 软件规模和复杂度在迅速膨胀, 给软件开发带来了新的问题:我们通常没有时间从头开发一个系统;而且, 常常在新系统交付之前, 用户的需求却发生了变化。如何复用已经存在的系统?如何能在尽可能保留我们已有成果的基础上充分应对用户的需求变更?在中等规模的软件产品中, “模式”便显现出决定性的作用。

关键词:软件,模式,Java

参考文献

[1] 林丽清.Java设计模式在评分程序中的应用[J].福建电脑, 2009 (8) :164~165.

[2] 陈海洋.Java设计模式研究[J].软件导刊, 2007 (11) :105~107.

[3] 汤韬.Java设计模式实战[J].程序员, 2003 (6) :50.

上一篇:论如何提高职校幼教专业的钢琴教学水平下一篇:贵州民族特色产品的电子商务发展现状及其对策研究——以三都水族马尾绣为例