您的位置:首页 > 职场人生

黑马程序员_IO流-装饰设计模式

2012-06-23 10:08 399 查看
------------------------------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)

                
4000
  {

                           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.csdn.net/heima

--
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息