(15)使用“接口”之搜索文件夹下指定类型的文件

上篇扩展了怎样用封装的形式去搜索不同类型的文件。【理解“封装”之搜索文件夹下指定类型的文件在我们将搜索不同类型文件的操作封装成一个方法后,看上去似乎是完工了。但是此刻,老板突然过来,说:这个程序不错,可以做成一个jar给公司的其他同事用。

我们把它打包成jar包,发给老板,老板说:我想搜包含"java"这个单词的所有文件。于是我们在isSearchFile里面加了段模糊搜索的逻辑,又打了个jar包给老板。

这时他又说:我想搜不包含"java"这个单词的所有文件。我们又加了段搜索不包含"xxx"单词的逻辑。

老板又说:我想搜索"test1.java","test2.java","test3.java"这样的数字后缀的文件,含英文或其他字符的不要。于是我们又加了段逻辑。

这时我们回过头一看,searchFile已经是很长的一段代码了,我们没有立刻把jar包给老板,而是在想,这样下去不行,鬼知道他待会又要搜索什么东西。

我们觉得,我们的代码需要优化一下。但是该怎样优化呢?我们无法预测到老板想要的所有搜索条件,既然是要面对未知的事物,那我们就用接口吧。

我们把isSearchFile方法抽象成了一个接口。如下

						/**
						 * 接口
						 *
						 * @author liuming
						 * @since 2016-9-23
						 */
						public interface FileSearchService {
							/***
							 * 文件搜索接口
							 * @param path
							 * @return
							 */
							boolean isSearchFile(String path);
						}


在FileSearch里面简单的实现了这个接口,并向外提供一个实例化接口的方法。

						/**
						 * 文件搜索
						 *
						 * @author liuming
						 * @since 2016-9-23
						 */
						public class FileSearch {
							/***
							 * 文件搜索接口
							 */
							private FileSearchService searchService=new FileSearchService() {
								@Override
								public boolean isSearchFile(String path) {
									return false;
								}
							};
							/**  
							 * 设置文件搜索接口  
							 * @param searchService 文件搜索接口  
							 */
							public void setSearchService(FileSearchService searchService) {
								this.searchService = searchService;
							}
							/**
							 * 文件搜索主程序
							 * @param path
							 */
							public void searchFolder(String path){
								File file=new File(path);
								if(file.exists()){
									File[] files=file.listFiles();
									if(files.length>0){
										for(int i=0;i<files.length;i++){
											if(files[i].isDirectory()){
												System.out.println(">>>进入文件夹:"+files[i].getAbsolutePath());
												searchFolder(files[i].getAbsolutePath());
											}else{
						//                        if(isSearchFile(files[i].getAbsolutePath())){
						//                            System.out.println(files[i].getAbsolutePath());
						//                        }
												if(searchService.isSearchFile(files[i].getAbsolutePath())){
													System.out.println(files[i].getAbsolutePath());
												}
											}
										}
									}else{
										System.out.println(path+"[文件夹下没有文件夹或文件]");
									}
								}else{
									System.out.println(path+"[文件夹不存在]");
								}
							}
						}

上章的内容在测试代码中我们这样写:

						/**
						 * 测试类
						 *
						 * @author liuming
						 * @since 2016-9-23
						 */
						public class FileSearchTest {
							public static void main(String[] args) {
								FileSearch fsearch=new FileSearch();
								fsearch.setSearchService(service);
								fsearch.searchFolder("D:\\aa");
								System.out.println("======搜索含有'2016'字符串的文件======");
								fsearch.setSearchService(searchStrService);
								fsearch.searchFolder("D:\\aa");
							}
							
							/**允许搜索的文件类型*/
							public final static String[] SEARCH_TYPE=new String[]{".mp4",".rmvb",".avi",".jpg","qvod.exe"};
							/**声明一个接口实现对象*/
							private static FileSearchService service=new FileSearchService() {
								@Override
								public boolean isSearchFile(String path) {
									for(int i=0;i<SEARCH_TYPE.length;i++){
										if(path.toLowerCase().endsWith(SEARCH_TYPE[i])){
											return true;
										}
									}
									return false;
								}
							};
							
							private static FileSearchService searchStrService=new FileSearchService() {
								@Override
								public boolean isSearchFile(String path) {
									if(path.indexOf("2016")!=-1){
										return true;
									}
									return false;
								}
							};
						}

改完之后,我们把代码打成jar包,发给老板(附带了测试文件的代码)。

没过多久,老板又说:HI,Boy,我想搜索test开头的没有数字结尾的文件。

"我们已经提供了接口,自己参考测试文件去写!"

对比这个用接口实现的文件搜索,很明显比用一个方法更加灵活。使用接口,完全的将文件搜索这个动作抽离出来,FileSearchService做什么处理和FileSearch的业务逻辑没有任何关系。至此,我们去修改文件搜索的逻辑已经和FileSearch没有任何关系了。