Java 的设计模式之一装饰者模式(2)

在添加 不同功能的时候。我们会想到了用继承来实现。而且刚学装饰者模式的时候,觉得挺难理解的,装饰者的前世今生就是继承。那为什么不用继承呢?这样岂不是更容易理解,用起来也挺方便。下面通过一个简单的Demo做一下比较。

需求:用继承来实现通过readLine读取代码  ,每一行加上一个行号和分号的功能

//1.添加行号,默认继承BufferedReader class BufferedReaderLineNum extends BufferedReader { int count = 0; public BufferedReaderLineNum(BufferedReader in) { //Reader:默认创建一个目标文件的缓冲字符输入流的大小 super(in); } @Override//3.重写父类的readLine方法 public String readLine() throws IOException { String countent = super.readLine();//调用父类默认的行号 if (countent == null) { return null; } //System.out.println(count + " " + countent); count++; return count + " " + countent; } } //添加分号 class BufferedReaderSemicolon extends BufferedReader {
BufferedReader reader;
public BufferedReaderSemicolon(BufferedReader in) {//Reader:默认创建一个目标文件的缓冲字符输入流的大小 super(in); this.reader = in; } @Override//3.重写父类的readLine方法 public String readLine() throws IOException { String countent = reader.readLine(); if (countent == null) { //判断数据已经读完 return null; } return countent + ";"; } } public class Demo1 { public static void main(String[] args) throws IOException { //FileReader用于字符输入流,FileInputStream是用字节输入流 //1.创建通道,拿到一个指定的目标文件 FileReader fileRead = new FileReader("C:\\java\\decorator\\Test.java"); BufferedReader reader = new BufferedReader(fileRead); //2.创建行号的缓冲流 BufferedReaderLineNum readerLineNum = new BufferedReaderLineNum(reader); //.创建分号的缓冲流 BufferedReaderSemicolon readerSemicolon = new BufferedReaderSemicolon(readerLineNum); String content = null; //使用readLine(),包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null while((content = readerSemicolon.readLine()) != null) { System.out.println(content); } //4.关闭资源 readerLineNum.close(); } } 

然后再通过装饰者模式来实现上面的功能:

//添加行号 class BufferederReadLineNum extends BufferedReader { BufferedReader bufferedReader; //1.内部维护的被装饰者的类 int count = 1; public BufferederReadLineNum(BufferedReader read) { super(read);//如果没有这行代码,会显示编译报错,显示没有隐式性的给这个构造函数定义 this.bufferedReader = read; } @Override public String readLine() throws IOException { String countent = bufferedReader.readLine(); if(countent == null) { return null; } countent = count + " " + countent; count++; return countent; } } //2.添加分号 class BufferedReaderSemicolon1 extends BufferedReader { BufferedReader bufferedReader; //1.内部维护的被装饰者的类 public BufferedReaderSemicolon1(BufferedReader read) { super(read); this.bufferedReader = read; } @Override//3.重写父类的readLine方法 public String readLine() throws IOException { String countent = super.readLine(); //调用父类默认的行号 if (countent == null) { //判断数据已经读完 return null; } return countent + ";"; } } public class Test2 { public static void main(String[] args) throws IOException { //1.创建通道,拿到一个指定的目标文件 FileReader fileRead = new FileReader("C:\\java\\代码\\src\\Test.java"); //2.创建缓冲区 BufferedReader bufferedReader = new BufferedReader(fileRead); //3创建分号的缓冲流 BufferedReaderSemicolon1 readerSemicolon = new BufferedReaderSemicolon1(bufferedReader); //创建行号的缓冲流 在装饰者创建的 BufferederReadLineNum readerLineNum = new BufferederReadLineNum(readerSemicolon); //4.读取数据 String content = null; //使用readLine(),包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null while((content = readerLineNum.readLine()) != null) { System.out.println(content); } //5.关闭资源 readerLineNum.close(); } }

通过上面的代码,可能不能完全看出使用装饰者模式的强大功能,你可以在多创建几个类,添加多个功能,结果就显而易见了。

在实现多个功能的时候,使用继承的体系会过于庞大,显得很臃肿。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/53dc9f57563822bd6e6ba24cc2e38ebd.html