JavaSE笔记15.3-IO流-装饰设计模式

JavaSE笔记15.3-IO流-装饰设计模式

1. 定义

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

2. 用法

(1)装饰类通常会通过构造方法接收被装饰的对象,并基于被装饰对象的功能,提供更强的功能
(2)装饰类因为增强已有对象,具备的功能和已有的是相同的,只不过提供了更强功能。所以装饰类和被装饰类通常都是属于一个体系中的

//被装饰类
class Person{
    public void lunch(){
        System.out.println("fruit");
    }

}
//装饰类
class SuperPerson{
    private Person p;
    //将已有对象传入
    SuperPerson(Person p){
        this.p=p;
    }
    //基于已有的功能,提供增强功能
    public void superLunch(){
        p.lunch();
        System.out.println("dessert");
        System.out.println("vegetables");
    }
}
public class PersonDemo {
    public static void main(String[] args) {
        Person p=new Person();
        SuperPerson sp=new SuperPerson(p);
        sp.superLunch();
    }
}

3. 装饰和继承的区别

例子:有一个专门用于读取数据的父类MyReader,根据读取的格式不同扩展了子类MyTextReader、MyMediaReader、MyDataReader,现在要给这3个子类增加缓冲功能

用继承的模式:

MyReader
    |--MyTextReader
        |--MyBufferedTextReader
    |--MyMediaReader
        |--MyBufferedMediaReader
    |--MyDataReader
        |--MyBufferedDataReader     

用装饰的模式:

MyReader
    |--MyTextReader
    |--MyMediaReader
    |--MyDataReader
    |--MyBufferedReader

  class MyBufferedReader extends MyReader{
      MyBufferedReader(MyReader r)//利用多态,如MyReader r=new MyTextReader()
  }  

继承和装饰的区别:
装饰模式比继承继承更灵活,避免了继承体系的臃肿,而且降低了类与类之间的耦合性。

4. 例子

需求:
自定义具有读一行文本功能的装饰类MyBufferedReader,被装饰类是Reader;
基于Reader对象的读单个字符功能read(),提供读一行文本的增强功能myReadLine()

import java.io.*;

//自定义装饰类MyBufferedReader
//装饰类和被装饰类通常属于同一体系,所以继承了Reader
class MyBufferedReader extends Reader{
    //装饰模式,通过构造方法接收被装饰的对象
    private Reader r;
    MyBufferedReader(Reader r){
        this.r=r;
    }

    //自定义一个读取一行文本的方法
    public String myReadLine() throws IOException {
        //原BufferedReader中的readLine方法封装的是字符数组
        //为了演示方便,定义一个临时容器StringBuilder,StringBuilder长度可变并且最终可通过toString方法变成字符串
        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类中的抽象方法
    @Override
    public int read(char[] cbuf, int off, int len) throws IOException {
        return r.read(cbuf,off,len);
    }

    @Override
    public void close() throws IOException {
        r.close();
    }
}

//使用装饰类MyBufferedReader
public class MyBufferedReaderDemo {
    public static void main(String[] args) {
        MyBufferedReader bufr=null;
        try{
            FileReader fr=new FileReader("buf.txt");
            bufr=new MyBufferedReader(fr);
            //向缓冲区中读数据
            String line=null;
            while ((line=bufr.myReadLine())!=null){
                System.out.println(line);
            }
        } catch (IOException e) {
            throw new RuntimeException("读写失败");
        }
        finally {
            try{
                if(bufr!=null)
                    bufr.close();
            } catch (IOException e) {
                throw new RuntimeException("关闭流失败");
            }
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值