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();
}
}