装饰设计模式、LineNumberReader

来源:互联网 发布:创维网络机顶盒e900 编辑:程序博客网 时间:2024/05/20 17:08

装饰设计模式:

 当想要对已有的对象进行功能增强时,可以定义一个类,将已有对象传入,基于已有对象的功能,并提供加强功能,那么自定义的该类就成为装饰类。

特点:装饰类通常会通过构造函数接收被装饰的对象,并基于被装饰的对象的功能,提供更强的功能。

例如:

public class MyBufferedReader  {
private Reader r;
    public MyBufferedReader(Reader r) {
super();
this.r = r;
}
//可以一次读取一行的方法
public String myReadLine() throws IOException
{
//定义一个临时容器。StringBulider容器,应用于存储字符数组
StringBuilder sb=new StringBuilder();
int ch=0;
while((ch=r.read())!=-1){
if(ch=='\r')
continue;
if(ch=='\n')
return sb.toString();
else
sb.append((char)ch);
}
if(sb.length()!=0)
return sb.toString();
return null;
}
//复写reader中的抽象方法
//复写close方法
public  void  close() throws IOException
{
r.close();
}
//复写read方法
public int read (char[] c,int off,int len) throws IOException{
return r.read(c, off, len);
}
}

装饰和继承的区别:

装饰模式比继承要灵活,避免了继承体系臃肿。而且降低了类与类之间的关系。装饰类因为是增强已有对象,具备的功能和已有对象是相同的,只不过提供了更强功能。所以装饰类和被装饰类通常都属于一个体系中的。

MyReader专门由于读取数据的类,

LineNumberReaderBufferedReader子类)

跟踪行号的缓冲字符输入流。

方法:setLineNumber(int):设置当前行号。

getLineNumber():获取当前行号。

默认情况下,行编号从0开始,该行号随数据读取在每个行结束符处递增,并可以通过调用setLineNumber更改行号,但是,setLineNumber不会实际更改流中的当前位置,它主要更改将由getLineNumber()返回的值。

练习:模拟一个带行号的缓冲区对象。

class MyLineNumberReader{

private Reader reader;

private int lineNumber;

public MyLineNumberReader(Reader reader){

this.reader=reader;

}

public String MyReadLine() throws IOException{

lineNumber++;//每读取一行时,行数自动加1一次

StringBuilder sb=new StringBuilder();

int ch=0;

while((ch=reader.read())!=-1){

if(ch=='\r')

continue;

if(ch=='\n')

return sb.toString();

sb.append((char)ch);

}

if(sb.length()!=0)

return sb.toString();

return null;

}

public void setLineNumber(int lineNumber){//设置行号

this.lineNumber=lineNumber;

}

public int getLineNumber(){//获取行号

return lineNumber;

}

public void myClose() throws IOException{

reader.close();

}

}

程序优化:由于缓冲区BufferedReader中已经实现了readLineclose方法,且在模拟读取字符流缓冲区时也自定义实现了readLineclose方法,在模拟带行号的缓冲对象时,再次实现readLineclose,代码重复,所以继承BufferedReader或者自定义的缓冲区类,可以减少代码的重复。

优化后的代码:

class MyLineNumberReader extends MyBufferedReader {

private int lineNumber;

public MyLineNumberReader(Reader r){

super(r);

}

public String MyReadLine() throws IOException{

lineNumber++;//每读取一行时,行数自动加1一次

return super.MyReadLine();

}

public void setLineNumber(int lineNumber){//设置行号

this.lineNumber=lineNumber;

}

public int getLineNumber(){//获取行号

return lineNumber;

}

}

0 0
原创粉丝点击