Java学习笔记之IO(十一):装饰者设计模式

package com.io.f_other;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;

import org.junit.Test;

/*

装饰者设计模式的提出:
	
	BufferedReader拓展了FileReader的功能;
	BufferedWriter拓展了FileWriter的功能;
	
 */

// 需求1:编写一个类拓展BufferedReader的功能,增强readLine()方法,使返回的数据带有行号;
class BufferedReadLineNum extends BufferedReader{

	private int lineNum = 1;
	
	public BufferedReadLineNum(Reader in) {
		super(in);
	}

	// 重写readLine()方法,使返回的数据带有行号;
	@Override
	public String readLine() throws IOException {
		
		String line = super.readLine();
		if (line == null){
			return null;
		}
	
		line = lineNum + " " + line;
		lineNum++;
	
		return line;
		
	}

}

//需求2:编写一个类拓展BufferedReader的功能,增强readLine()方法,使返回的每行数据末尾带有分号;
class BufferedReadLineSemi extends BufferedReader{

	public BufferedReadLineSemi(Reader in) {
		super(in);
	}
	
	@Override
	public String readLine() throws IOException {
	
		String line = super.readLine();
		if (line == null){
			return null;
		}
		
		line = line + ";";
		
		return line;
	}
	
}

//需求3:编写一个类拓展BufferedReader的功能,增强readLine()方法,使返回的每行数据都带有双引号;
class BufferedReadLineQuotation extends BufferedReader{

	public BufferedReadLineQuotation(Reader in) {
		super(in);
	}

	@Override
	public String readLine() throws IOException {
		
		String line = super.readLine();
		if (line == null){
			return null;
		}
		
		line = "“" + line + "”";
		
		return line;
	}
	
}

/*

通过需求1、2、3可以看出,增强一个类的功能我们可以选择使用继承;
	使用继承实现增强一个类的功能优点:代码结构清晰,通俗易懂;
	缺点:如果还有如下几个需求:就需要再创建四个自定义类;
		需求4:编写一个类拓展BufferedReader的功能,增强readLine()方法,使返回的每行数据都带有行号+分号;
		需求5:编写一个类拓展BufferedReader的功能,增强readLine()方法,使返回的每行数据都带有行号+双引号;
		需求6:编写一个类拓展BufferedReader的功能,增强readLine()方法,使返回的每行数据都带有分号+双引号;
		需求7:编写一个类拓展BufferedReader的功能,增强readLine()方法,使返回的每行数据都带有行号+分号+双引号;
		可以发现缺点是 使用不灵活,会导致继承的体系过于庞大;
		
	如果想更好的完成这七个需求,可以使用 装饰者设计模式;
		
 */

public class Demo1 {
	
	// 测试带行号的缓冲输入字符流
	@Test
	public void test1() throws IOException{
		// 找到目标文件
		File file = new File("D:\\Demo1.java");
		
		// 建立数据输入通道
		FileReader reader = new FileReader(file);
		
		// 建立带行号的缓冲输入字符流
		BufferedReadLineNum readerLine = new BufferedReadLineNum(reader);
		
		// 读取数据
		String line = null;
		while ((line = readerLine.readLine()) != null){
			System.out.println(line);
		}
		
		// 关闭资源
		readerLine.close();
	}
	
	// 测试带分号的缓冲输入字符流
	@Test
	public void test2() throws IOException{
		// 找到目标文件
		File file = new File("D:\\Demo1.java");
		
		// 建立数据输入通道
		FileReader reader = new FileReader(file);
		
		// 建立带分号的缓冲输入字符流
		BufferedReadLineSemi readerLine = new BufferedReadLineSemi(reader);
		
		// 读取数据
		String line = null;
		while ((line = readerLine.readLine()) != null){
			System.out.println(line);
		}
		
		// 关闭资源
		readerLine.close();
	}
	

	// 测试带双引号的缓冲输入字符流
	@Test
	public void test3() throws IOException{
		// 找到目标文件
		File file = new File("D:\\Demo1.java");
		
		// 建立数据输入通道
		FileReader reader = new FileReader(file);
		
		// 建立带双引号的缓冲输入字符流
		BufferedReadLineQuotation readerLine = new BufferedReadLineQuotation(reader);
		
		// 读取数据
		String line = null;
		while ((line = readerLine.readLine()) != null){
			System.out.println(line);
		}
		
		// 关闭资源
		readerLine.close();
	}
	
}

package com.io.f_other;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;

import org.junit.Test;

/*

装饰者设计模式:增强一个类的功能,而且还可以让这些类互相装饰;
	
	装饰者设计模式的步骤:
	1、在装饰类的内部维护一个被装饰类的引用;
	2、让装饰类有一个共同的父类或父接口;
		原因:为了让这些装饰类的对象可以作为参数进行传递,达到互相装饰的效果;
		
	继承实现的增强类和装饰者模式实现的增强类有什么区别?
	
	继承实现的增强类:
		优点:代码结构清晰,而且实现简单;
		缺点:对于每一个需要增强的类都要创建具体的子类来帮助其增强,导致继承体系过于庞大;
	
	装饰者模式实现的增强类:
		优点:内部可以通过多态技术对多个需要增强的类进行增强,可以使这些装饰类达到互相装饰的效果;
		缺点:需要内部通过多态技术维护需要被增强的类的实例,进而使得代码稍微复杂;
		
 */

// 带行号的缓冲输入字符流
class BufferedReaderLineNum extends BufferedReader{
	
	private int num = 1;
	
	// 在内部维护一个被装饰类的引用
	private BufferedReader bufferedReader;
	
	// 构造方法接收被装饰类对象
	public BufferedReaderLineNum(BufferedReader bufferedReader){
		super(bufferedReader); // 该语句没有任何作用,只是为了不报错;
		this.bufferedReader = bufferedReader;
	}
	
	// 自定义方法增强功能
	public String readLine() throws IOException{
		String line = bufferedReader.readLine();
		if (line == null){
			return null;
		}
		
		line = num + " " + line;
		num++;
		
		return line;
	} 
	
}

// 带分号的缓冲输入字符流
class BufferedReaderLineSemi extends BufferedReader{
	
	// 在内部维护一个被装饰类的引用
	private BufferedReader bufferedReader;
	
	// 构造方法接收被装饰类对象
	public BufferedReaderLineSemi(BufferedReader bufferedReader){
		super(bufferedReader);
		this.bufferedReader = bufferedReader;
	}
	
	// 自定义方法增强功能
	public String readLine() throws IOException{
		String line = bufferedReader.readLine();
		if (line == null){
			return null;
		}
		
		return line + ";";
	} 
	
}


public class Demo2 {

	// 测试带行号的缓冲输入字符流
	@Test
	public void test1() throws IOException{
		// 找到目标文件
		File file = new File("D:\\Demo1.java");
		
		// 建立数据的输入通道
		FileReader reader = new FileReader(file);
		
		// 建立缓冲输入字符流
		BufferedReader bufferedReader = new BufferedReader(reader);
		
		// 建立带行号的缓冲输入字符流
		BufferedReaderLineNum readerLineNum = new BufferedReaderLineNum(bufferedReader);
		
		// 读取数据
		String line = null;
		while ((line = readerLineNum.readLine()) != null){
			System.out.println(line);
		}
		
		// 关闭资源
		readerLineNum.close();
	}

	// 测试带分号的缓冲输入字符流
	@Test
	public void test2() throws IOException{
		// 找到目标文件
		File file = new File("D:\\Demo1.java");
		
		// 建立数据的输入通道
		FileReader reader = new FileReader(file);
		
		// 建立缓冲输入字符流
		BufferedReader bufferedReader = new BufferedReader(reader);
		
		// 建立带分号的缓冲输入字符流
		BufferedReaderLineSemi readerLineSemi = new BufferedReaderLineSemi(bufferedReader);
		
		// 读取数据
		String line = null;
		while ((line = readerLineSemi.readLine()) != null){
			System.out.println(line);
		}
		
		// 关闭资源
		readerLineSemi.close();
	}

	// 测试带行号+分号的缓冲输入字符流
	@Test
	public void test3() throws IOException{
		// 找到目标文件
		File file = new File("D:\\Demo1.java");
		
		// 建立数据的输入通道
		FileReader reader = new FileReader(file);
		
		// 建立缓冲输入字符流
		BufferedReader bufferedReader = new BufferedReader(reader);
		
		// 建立带行号的缓冲输入字符流
		BufferedReaderLineNum readerLineNum = new BufferedReaderLineNum(bufferedReader);
		// 建立带分号的缓冲输入字符流;
		// 如果调用的readLine()方法是BufferedReaderLineNum中的readLine()方法,那么就能实现两个增强类的功能;
		BufferedReaderLineSemi readerLineSemi = new BufferedReaderLineSemi(readerLineNum);
		
		// 读取数据
		String line = null;
		while ((line = readerLineSemi.readLine()) != null){
			System.out.println(line);
		}
		
		// 关闭资源
		readerLineSemi.close();
	}
	
}

猜你喜欢

转载自blog.csdn.net/qq_29331365/article/details/78202872