------------------------------android培训、java培训、期待与您交流! ----------------------------------------------------------------
装饰设计模式
理解:
对原有类进行了功能的改变,增强。
装饰模式的基本格式。
它与继承有什么不同?
了解BufferedReader的原理。
(1) 当想要对已有的对象进行功能增强时,可以定义类,将已有对象传入,基于已有的功能,并提供加强功能。那么自定义的该类称为装饰类。
需求:示例一个装饰模式的实现
class Person
{
publicvoid chifan()
{
System.out.println("吃饭");
}
}
class SuperPerson
{
privatePerson p ;
SuperPerson(Personp)
{
this.p = p;
}
//装饰类通常会通过构造方法接收被装饰的对象。并基于被装饰的对象的功能,提供更//强的功能。
publicvoid superChifan()
{
System.out.println("开胃酒");
p.chifan();
System.out.println("甜点");
System.out.println("来一根");
}
}
class PersonDemo
{
publicstatic void main(String[] args)
{
Person p = new Person();
//p.chifan();
SuperPerson sp = new SuperPerson(p);//基于原有功能增强了.
sp.superChifan();
}
}
问题:为什么不用继承?
MyReader //专门用于读取数据的类。抽取出来的父类.
|--MyTextReader
|--MyBufferTextReader
|--MyMediaReader
|--MyBufferMediaReader
|--MyDataReader
|--MyBufferDataReader
继承 体系结构臃肿, 扩展性很差。
重新定义结构有:都用的是缓冲技术,
class MyBufferReader
{
MyBufferReader(MyTextReadertext)
{}
MyBufferReader(MyMediaReadermedia)
{}
}
以前是通过继承将每一个子类都具备缓冲功能。那么继承体系会复杂,并不利于扩展。
现在优化思想。单独描述一下缓冲内容。将需要被缓冲的对象。传递进来。也就是,谁需要被缓冲,谁就作为参数传递给缓冲区。
这样继承体系就变得很简单。优化了体系结构。找到其参数的共同类型。通过多态的形式。可以提高扩展性。
class MyBufferReader extends MyReader// MyBufferReader有更强的功能
{
privateMyReader r;
MyBufferReader(MyReaderr)
{}
}
MyReader//专门用于读取数据的类。
|--MyTextReader
|--MyMediaReader
|--MyDataReader
|--MyBufferReader(可以调用以上类中的方法.)
装饰模式比继承要灵活。避免了继承体系臃肿。而且降低了类于类之间的关系。
装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过提供了更强功能。
所以装饰类和被装饰类通常是都属于一个体系中的。
由继承结构转为了组合结构.
需求:示类LineNumberReader的使用.加强装饰类的学习.
类 LineNumberReader
java.lang.Object
java.io.Reader
java.io.BufferedReader
java.io.LineNumberReader
此类定义方法 void setLineNumber(int)
和 intgetLineNumber()
,它们可分别用于设置和获取当前行号。
LineNumberReader是BufferedReader的装饰类.
注意:BufferedWriter
中没有对应的子类来装饰BufferedWriter
类.
在BufferedReader的构造方法中:
BufferedReader(
Reader in)
创建一个使用默认大小输入缓冲区的缓冲字符输入流。
传入的是 Reader 对象,则根据多态,也能传入FileReader,及Reader的子类.
同理:构造方法中有:
LineNumberReader(
Reader in)
使用默认输入缓冲区的大小创建新的行编号 reader。
import java.io.*;
class LineNumberReaderDemo
{
publicstatic void main(String[] args)throwsIOException //必须try.
{
FileReader fr =new FileReader("PersonDemo.java");
LineNumberReaderlnr = new LineNumberReader(fr);
String line = null;
lnr.setLineNumber(100);//行号从101开始.
while((line=lnr.readLine())!=null)
{
System.out.println(lnr.getLineNumber()+":"+line);取出行号的方法.
}
lnr.close();
}
}
需求: 练习模拟一个带行号的缓冲区对象。
class MyLineNumberReader
{
privateReader r;
private int lineNumber; //定义一个计数器.
MyLineNumberReader(Readerr) /传入被装饰的对象.
{
this.r = r;
}
publicString myReadLine()throws IOException
{
lineNumber++;
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)
returnsb.toString();
return null;
}
publicvoid setLineNumber(int lineNumber)
{
this.lineNumber = lineNumber;
}
publicint getLineNumber()
{
return lineNumber;
}
publicvoid myClose()throws IOException
{
r.close();
}
}
写 一个类来测试一下MyLineNumberReader
class MyLineNumberReaderDemo
{
publicstatic void main(String[] args) throws IOException
{
FileReader fr = newFileReader("copyTextByBuf.java");
MyLineNumberReader mylnr = newMyLineNumberReader(fr);
String line = null;
mylnr.setLineNumber(100);//从100开始
while((line=mylnr.myReadLine())!=null)
{
System.out.println(mylnr.getLineNumber()+"::"+line);
}
mylnr.myClose();
}
}
-----------------------------android培训、java培训、期待与您交流! ----详细请查看:http://edu.youkuaiyun.com/heima
--