常用设计模式__之【装饰设计模式】

来源:互联网 发布:男生基本款衬衫 知乎 编辑:程序博客网 时间:2024/04/28 13:20


装饰模式的体现之一:

BufferedReader 类中readLine()方法

原理readLine()调用的还是read()方法,在硬盘上一个一个的读取,暂时存储起来,当读取到换行符时就把读取的值返回完成一行数据的读取

模拟BufferedReader类中readLine方法

import java.io.*;class MyBufferedReader {private FileReader r;//私有化成员变量MyBufferedReader(FileReader r)//将读取流对象传入构造函数{this.r=r;}public String myReadLine() throws IOException//可以一次读取一行的方法{//定义临时容器,原BufferReader封装了字符数组StringBuilder sb = new StringBuilder();//最终数据还是要转成字符串,为了方便,定义StringBuilder容器int ch = 0;while ((ch=r.read()) !=-1){if (ch=='\r')//Windows中java换行符是 \r\ncontinue;//if (ch=='\n')return sb.toString();//当读取到换行时,将缓冲区中字符串返回elsesb.append((char)ch);//读取不到换行,缓冲区就一直增加,由于ch是read返回的该字符在码表中的int值,所以要强转}if(sb.length() !=0)//此判断是为了处理文件末尾没有换行符的情况return sb.toString();return null;//方法明确了返回值为String,}public void myClose() throws IOException{r.close();}}
readLine()是read()方法的增强,BufferedReader是FileReader类的增强类,
将被增强类的对象作为参数传入增强类 

装饰设计模式

当想要对已有对象进行功能增强时,可以定义类,将已有对象传入,基于已有的功能,提供加强功能,自定的该类称为装饰类

示例:

class Person{public void eat(){System.out.println("吃饭");}}class SuperPerson{//装饰类private Person p;//将被装饰的类作为成员变量SuperPerson(Person p){//嵌入到装饰类this.p = p;}public void superEat(){//装饰类更强大的功能System.out.println("开胃菜");p.eat();System.out.println("饭后甜点");System.out.println("Smoke~");}}class  DecorateDemo{public static void main(String[] args) {Person p = new Person();SuperPerson sp = new SuperPerson(p);sp.superEat();}}

装饰和继承的关系:

通过继承生成子类同样可以达到扩展功能的效果,但是相比之下,装饰模式降低了两个类之间的关联度,具有更高的灵活性和扩展性

MyReader//专门用于读取数据的类。|--MyTextReader|--MyBufferTextReader|--MyMediaReader|--MyBufferMediaReader|--MyDataReader|--MyBufferDataReader
class MyBufferReader{MyBufferReader(MyTextReader text){}MyBufferReader(MyMediaReader media){}}
上面这个类扩展性很差。找到其参数的共同类型。通过多态的形式。可以提高扩展性。

class MyBufferReader extends MyReader{//组合结构private MyReader r;MyBufferReader(MyReader r){}}

通过继承将每一个子类都具备缓冲功能。而继承体系比较复杂,并不利于扩展。
现在优化思想。单独描述一下缓冲内容。将需要被缓冲的对象。传递进来。
也就是,谁需要被缓冲,谁就作为参数传递给缓冲区。这样继承体系就变得很简单。优化了体系结构。

优化后的体系:

MyReader//专门用于读取数据的类。|--MyTextReader|--MyMediaReader|--MyDataReader|--MyBufferReader//

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

装饰模式的体现之二:

BufferedReader的子类LineNumberReader
主要方法:setLineNumber(int x),设置当前行号
和getLineNumber(),获得当前行号

示例:

import java.io.*;class  LineNumberReaderDemo{public static void main(String[] args) throws IOException{FileReader fr = new FileReader("LineNumberReaderDemo.java");LineNumberReader lnr = new LineNumberReader(fr);String line = null;lnr.setLineNumber(10);//设置当前行号while ((line=lnr.readLine()) !=null){System.out.println(lnr.getLineNumber()+" : "+line);}lnr.close();}}

手动模拟实现一个LineNumberReader类

class MyLineNumberReader extends MyBufferedReader //继承,参考之前的readLine()实现{MyLineNumberReader(Reader r){//继承自父类,省略成员的私有化步奏super(r);}public String myReadLine() throws IOException{lineNumber++;//相对于父类的readline()仅增加了计数功能return super.myReadLine();//继承自父类}public void setLineNumber(int lineNumber){//子类特有方法this.lineNumber = lineNumber;}public int getLineNumber(){//子类特有方法return lineNumber;}//关闭流的动作父类中已经实现了,不需要再覆盖,直接调用即可}


4 0
原创粉丝点击