作者:Flyingis
任何程序語言的I/O設(shè)計都是一項具有挑戰(zhàn)的任務(wù),因為數(shù)據(jù)的傳輸存在多種可能,這些可能不僅存在于數(shù)據(jù)發(fā)送端和接收端(文件、網(wǎng)絡(luò)鏈接等),還存在于這些數(shù)據(jù)的多種存在方式,例如緩沖區(qū)數(shù)據(jù)、順序存取數(shù)據(jù)、字符數(shù)據(jù)、字節(jié)數(shù)據(jù)等等。
Java的I/O使用“流”這個抽象的概念,它屏蔽了實際的I/O設(shè)備中處理數(shù)據(jù)的細(xì)節(jié)。在實際的應(yīng)用中,我們很少使用單一的類來創(chuàng)建流對象,而是通過多個對象來提供所需要的I/O功能。Java從1.0到1.1到1.4多I/O類庫作了多次重大修改,具體的可以參考相關(guān)的書籍或Sun官方網(wǎng)站。這里是從模式的角度來分析Java的I/O類庫的設(shè)計。
Strategy設(shè)計模式
將會發(fā)生變化的代碼封裝在單獨的類(Strategy對象)中,供其他保持不變的類使用,實現(xiàn)某種算法或應(yīng)用,這是Strategy設(shè)計模式的一般思想。在Java I/O中,一個典型的應(yīng)用是File類,它可以代表一個特定文件的名稱,也可以代表一個目錄下一組文件的名稱。當(dāng)我們要查詢顯示一個目錄下特定文件類型的所有文件對象信息時,就需要將這個目錄下的文件過濾,找到所需要的對象。
import java.io.*;
import java.util.*;
import java.util.regex.*;
public class AlphabeticComparator implements Comparator {
public int compare(Object o1, Object o2) {
String s1 = (String)o1;
String s2 = (String)o2;
return s1.toLowerCase().compareTo(s2.toLowerCase()); //比較時不考慮大小寫
}
}
public class FruitList {
public static FilenameFilter filter(final String regex) {
return new FilenameFilter() {
private Pattern pattern = Pattern.compile(regex);
public boolean accept(File dir, String name) {
return pattern.matcher(new File(name).getName()).matches();
}
};
}
public static void main(String[] args) {
File path = new File(“.”);
String[] list;
if (args.length == 0)
list = path.list(); //搜索出該目錄下所有類型的文件
else
list = path.list(filter(args[0])); //搜索出該目錄下指定類型的文件
Arrays.sort(list, new AlphabeticComparator());
for (int i = 0; i < list.length; i++)
System.out.println(list[i]);
}
}
在上述代碼中,有兩個地方使用了Strategy設(shè)計模式,一個是AlphabeticComparator類,用來在忽略字符串大小寫的情況下提供排序的規(guī)則,另一個就是FilenameFilter接口,使用了匿名內(nèi)部類的設(shè)計,然后將其中實現(xiàn)的accept()規(guī)則提供給File類的list方法使用。這里是用來判斷正則表達(dá)式regex是否和文件名匹配,當(dāng)運行程序在命令操作符中輸入“E.*\.java”時,搜索到的是該目錄下所有.java文件。
File類除了上述用法外,還可以創(chuàng)建或刪除目錄,查看文件的信息,包括文件大小、最后修改日期,讀寫狀態(tài)等,具體的可以參考JDK文檔。
Decorator設(shè)計模式
在http://www.j2eesp.com上有對Decorator設(shè)計模式的定義:動態(tài)給一個對象添加一些額外的職責(zé),就像在墻上刷油漆。使用Decorator模式相比用生成子類方式達(dá)到功能的擴(kuò)充顯得更為靈活。Decorator模式規(guī)定所有封裝于初始對象內(nèi)部的對象具有相同的接口,這使得該模式的應(yīng)用具有透明性。
在Java I/O設(shè)計中,Decorator模式主要體現(xiàn)在filter類的設(shè)計上,抽象類filter是所有Decorator模式類的基類。但是Decorator模式同樣存在缺點:在編寫程序時,它在給開發(fā)人員提供了靈活性的同時,增加了代碼的復(fù)雜性,造成了Java I/O類操作不便,因為很多I/O設(shè)計中都需要應(yīng)用Decorator模式,增加一些類來完成該設(shè)計。
例如在Java 1.0中,FilterInputStream從InputStream中讀取數(shù)據(jù),FilterOutPutStream向OutputStream中寫入數(shù)據(jù),在Java 1.1中,相應(yīng)的有FilterReader和FilterWriter(抽象類,沒有子類)用于Decorator模式設(shè)計。舉個簡單的例子:
import java.io.*;
public class DecoratorDemo {
public static void main(String[] args) {
BufferedReader in = new BufferedReader(new FileReader(“FruitList.java”));
String s = new String();
while ((s = in.readLine()) != null)
System.out.println(s);
in.close();
}
}
BufferedReader和FileReader完成了Decorate模式設(shè)計,這兩個類可以更換為其他具有相同功用的類(在Thinking in Java中稱為“修飾器”類)來組合完成特定的任務(wù),正如上文所述,這給開發(fā)者提供了多種組合方式,同時也相對的增加了復(fù)雜度。
最后,祝blogjava所有成員和Java、開源愛好者元旦快樂!幸福安康!