Java中的装饰者模式、LineNumberReader、打印流(基础解析)

本文详细介绍了装饰者模式的应用实例,包括BufferedOutputStream和PrintStream等类如何通过装饰者模式增强原始功能,提高效率,并实现了LineNumberReader的自定义装饰者模式。

装饰者模式(设计模式)

    思想: 可以通过装饰 对原来的功能进行升级
    BufferedOutputstream
    需要 Outputstream 构造
    可以使 FileOutputStream(被装饰者)
    相当于装饰后 功能得到了提升 写入效率提高了

    ObjectOutputstream
    需要 Outputstream 构造
    可以使用 FileOutputStream

    通过ObjectOutputstream 装饰后
    功能提升 可以写对象了

    装饰者模式流程
    1.把被装饰者 写成成员变量
    2.构造方法中 给该成员变量赋值
    3.对原有功能的升级

LineNumberReader(读行)

    public static void fun1() throws FileNotFoundException, IOException {
        FileReader fr = new FileReader("/Users/lanou/Desktop/Test/hh.txt");
        LineNumberReader lnr = new LineNumberReader(fr);
        //设置开始的行号
        lnr.setLineNumber(10);
        String string = "";
        while ((string = lnr.readLine()) != null) {

            System.out.println(string + ": " +  lnr.getLineNumber());
            }
        lnr.close();
        }
    }
    利用装饰者模式 实现 LineNumberReader
    被装饰者 Reader
    1.把read()方法升级 读行
    2.带行号
    3.关闭资源功能升级

    class UpToLineNumberReader{
        private Reader r;
        // 记录行号
        private int num = 0;
        // 有参无参构造方法
        public UpToLineNumberReader(){

        }
        public UpToLineNumberReader(){

        }
        // set/get方法
        public int getNum() {
        return num;
    }

        public void setNum(int num) {
            this.num = num;
        }
        // 功能升级 从读字节 升级到 读行
        public String upToRead() throws IOException {
            // 方法走一次 就代表读了一行
            num++;
            // 拼接字符串
            StringBuilder stringBuilder = new StringBuilder();
            int len = 0;
            while ((len = r.read()) != -1){
                // 进行拼接
                // 遇到换行 这一行字符串已经拼接完毕 直接返回就行
                // ASCII中 10 就代表换行 相当于"\n"
                if(len == 10){
                    return stringBuileder.toString();
                }else{
                    // 不换行 就拼接字符串
                    string.Builder.append((char)len);
                }
            }
            // 读完了 没有内容可以继续拼接了
            if (stringBuilder.length() == 0) {
                return null;
            }
            return stringBuilder.toString();
        }
        // 关闭资源
        public void closeUpToRead() throws IoException {
            r.close();
        }
    }

打印流

    PrintStream(输出字节)
    构造方法可接收的参数:
        1.文件(File)
        2.字节输出流(Outputstream)
        3.文件路径
    PringWriter(输出字符)
        1.只能作为数据的目的地
        2.可以把数据原样输出
        3.永远不会抛出IOException
            但是 可以抛出 其他异常 例如: 空指针
        4.打印流相当于 可以给其他的流对象 装饰了一个 原样输出的功能

打印字节流

    public static void fun1() throws FileNotFoundException {
        // 创建文件
        File file = new File("/Users/lanou/Desktop/Test/hh1.txt");

        FileOutputStream fos = new FileoutputStream(file);
        //创建缓冲字节输出流
        BufferedOutputstream bos = new BufferedOutputstream(fos);
        //创建一个打印字节流
        PrintStream ps = new PrintStream(bos);
        //写数据
        ps.println("aa");
        ps.println(true);
        ps.println(100);
        ps.println(3.5);
        ps.write(100);
        ps.println('p');
        // 关闭资源
        ps.close();
    }

打印字符流

    // 打印字符流
    public static void fun2() throws FileNotFoundException {
        // 打印字符流
        // 创建文件
        File file = new File("/Users/lanou/Desktop/Test/hh1.txt");
        //创建打印字符流
        PrintWriter pw = new PrintWriter(file);
        pw.println("aa");
        pw.println(200);
        pw.println(false);
        pw.write('c');
        // 刷新
        pw.flush();
        // 关闭资源
        pw.close();
    }   
    System.in 是 BufferedInputStream 缓冲输入字节流

    System.out 是 PrintStream 打印输出字节流
    作用: 输出内容到控制台
    public class Demo03 {
        public static void main(String[] args) throws IOException {
            System.out.println("请输入");
            // 读取从键盘输入的数据
            Inputstream in = System.in;
            StringBuilder stringBuilder = new StringBuilder();
            int len = 0;
            while(true){
                if(stringBulider.toString().equals("quit")){
                    break;
                }
                // 读取数据 拼接数据
                len = in.read();
                if (len == 10) {
                    System.out.println(stringBuilder.toString());
                    // 清空缓冲字符串
                    stringBulider.delete(0, stringBulider.length());
                }else {
                    stringBulider.append((char)len);
                }
            }
        }
    }   


                                        Day.27

http://blog.youkuaiyun.com/ssssssue

<think>好的,用户想找Java装饰模式的示例代码。我需要根据提供的引用内容来组织回答。首先,查看用户提供的引用,其中引用2和引用4有具体的代码示例。引用2展示了一个简单的装饰模式代码,包括组件接口、具体组件、装饰器抽象类和具体装饰器。引用4中的电脑类可能也是一个例子的一部分,但需要结合其他类来完整说明。另外,引用5提到IO库中的应用,比如BufferedInputStream,但用户可能需要更具体的代码示例。 我应该先介绍装饰模式的基本结构,然后给出引用中的代码示例。需要确保代码符合Java语法,并解释各个部分的作用。可能还需要提到IO库中的应用,如引用1、3、5提到的,但用户主要需要示例代码,所以重点放在引用2和引用4的例子上。 需要检查引用中的代码是否完整。引用2的示例包括接口Component,具体组件ConcreteComponent,抽象装饰器Decorator,以及具体装饰器ConcreteDecoratorA和B。这可能是一个完整的例子。引用4的电脑类可能需要装饰器类来扩展功能,比如添加内存或显卡,但用户提供的引用中没有完整的代码,可能需要补充说明。 另外,要确保回答结构清晰,分步骤解释,并引用正确的来源。例如,引用2提供了基础示例,引用5提到IO库的应用,但用户可能需要更详细的代码,所以可以建议查看Java的IO类源码,如BufferedWriter等,如引用3所述。 需要确认是否要提供多个示例,比如基础示例和IO库中的实际应用示例。用户的问题可能希望看到两种类型的代码,所以最好都包括进去。例如,先展示一个简单的自定义示例,然后提到Java IO中的使用,并解释如何通过装饰器扩展功能。 最后,生成相关问题,可能涉及装饰模式的其他应用场景、优缺点,或者与继承的比较等。需要根据引用内容中的信息来生成相关问题,例如引用5提到的应用场景,可以相关问题询问这些场景的具体实现。</think>以下为Java装饰模式的示例代码及详细说明: ### 一、基础代码结构 1. **组件接口**:定义核心功能 ```java // 引用[2] public interface Coffee { String getDescription(); double cost(); } ``` 2. **具体组件**:实现基础功能 ```java // 引用[2] public class SimpleCoffee implements Coffee { @Override public String getDescription() { return "基础咖啡"; } @Override public double cost() { return 2.0; } } ``` 3. **装饰器抽象类**:持有一个组件对象 ```java // 引用[2] public abstract class CoffeeDecorator implements Coffee { protected Coffee decoratedCoffee; public CoffeeDecorator(Coffee coffee) { this.decoratedCoffee = coffee; } } ``` 4. **具体装饰器**:添加新功能 ```java // 引用[2] public class MilkDecorator extends CoffeeDecorator { public MilkDecorator(Coffee coffee) { super(coffee); } @Override public String getDescription() { return decoratedCoffee.getDescription() + "+牛奶"; } @Override public double cost() { return decoratedCoffee.cost() + 0.5; } } ``` ### 二、Java IO库中的实际应用 ```java // 引用[1][3][5] // 基础组件 FileReader fileReader = new FileReader("data.txt"); // 装饰器添加缓冲功能 BufferedReader bufferedReader = new BufferedReader(fileReader); // 再次装饰添加行号功能 LineNumberReader lineReader = new LineNumberReader(bufferedReader); ``` ### 三、电脑配置示例 ```java // 引用[4] // 基础电脑类 public class BasicComputer { public String getDescription() { return "基础电脑"; } public int getPrice() { return 5000; } } // 内存装饰器 public class MemoryDecorator extends ComputerDecorator { public MemoryDecorator(Computer computer) { super(computer); } @Override public String getDescription() { return super.getDescription() + "+16G内存"; } @Override public int getPrice() { return super.getPrice() + 800; } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值