69. 装饰者设计模式

当类中的某些功能不满足我们的需求的时候,我们可以使用继承,重写此方法来实现我们的需求


继承:子类构造方法第一句话必须调用父类的构造方法,并且子类继承父类的成员变量和方法(除了私有成员和构造方法)

需求1:读取文本并显示行数
分析:使用缓存输入字符流,只能输出文本,并不会显示行数,那么我们需要重写BufferedReader的readLine

class LineBufferedReader extends BufferedReader{
    
    //行数
    int count = 1;
    
    //注意:子类构造方法第一句话必须调用父类的构造方法
    //BufferedReader没有无参数的构造方法,所以我们需要指定调用父类的其中一个构造方法
    public LineBufferedReader(Reader in) {
        super(in);
    }
    //重写readLine方法
    @Override
    public String readLine() throws IOException {
        //接受父类的readLine()的内容
        String line =  super.readLine();
        //父类的readLine方法,读取到文本的末尾时会返回null
        if(line != null) {
            String newline = count+line;
            count++;
            return newline;
        }else {
            //如果父类的readLine方法返回null,那么表示已经到末尾了,直接返回line(null)
            return line;
        }
    }
}


public class Demo1 {
    public static void main(String[] args) throws IOException {
        //找到目标文件
        File file = new File("D:\新建文件夹\1.txt");
        //建立数据传输通道
        FileReader fileReader = new FileReader(file);
        
        LineBufferedReader bufferedReader = new LineBufferedReader(fileReader);
        String line = "";
        while((line = bufferedReader.readLine())!=null) {
            System.out.println(line);
        }
        bufferedReader.close();
    }
}

需求2:读取文本并在每一行后面加一个逗号
需求3:读取文本并在每一行后面加一个分号
需求4:读取文本并显示行数且在每一行后面加一个逗号
需求5:读取文本并显示行数且在每一行后面加一个分号
需求6:读取文本并显示行数且在每一行后面加一个分号和逗号
等等....
这样每有一个需求,我们就要定义一个类并重写readLine方法,导致继承体系过于庞大,而且不灵活

装饰者设计模式可以达到同样的效果,并且我们只需要实现前三个需求就可以组合完成其他需求,这样大大减少了继承体系,并且更灵活

装饰者设计模式:增强一个类的功能,并且还可以让这些装饰类互相装饰

装饰者设计模式的步骤:
    1.让装饰类有一个共同的父类和父接口(只有继承或者实现关系才能使用多态)
    2.在内部维护一个被装饰的类的引用(这样是为了使用多态来完成互相装饰的效果)

装饰者设计模式,和继承的优缺点:
    继承
        优点:代码结构清晰,易理解,而且实现简单
        缺点:对于每一个需求,都需要增强的子类实现,导致继承体系过于庞大,而且不灵活
    装饰者设计模式
        优点:内部使用多态技术,对多个需要增强的类进行增强,可以使这些装饰类达到互相装饰的效果,比较灵活
        缺点:需要使用多态技术维护需要被增强的类,使代码稍微复杂了点

//给读取的文本添加行号
class LineBufferedReader extends BufferedReader{
    //在内部维护一个被装饰的类的引用
    BufferedReader bufferedReader;
    
    //行数
    int count = 1;
    
    public LineBufferedReader(BufferedReader bufferedReader) {//参数---多态
        super(bufferedReader);//在装饰者设计模式中。此语句没有任何作用只是为了防止报错
        this.bufferedReader = bufferedReader;
    }
    
    //重写readLine方法
    @Override
    public String readLine() throws IOException {
        //调用传入对象的readLine方法
        String line = bufferedReader.readLine();
        if(line != null) {
            String newline = count+line;
            count++;
            return newline;
        }else {
            return line;
        }    
    }
}

//给每一个文本添加分号
class SemicolonBufferedReader extends BufferedReader{
    //在内部维护一个被装饰的类的引用
    BufferedReader bufferedReader;
    
    public SemicolonBufferedReader(BufferedReader bufferedReader) {//参数---多态
        super(bufferedReader);//在装饰者设计模式中。此语句没有任何作用只是为了防止报错
        this.bufferedReader = bufferedReader;
    }
    
    //重写readLine方法
    @Override
    public String readLine() throws IOException {
        //调用传入对象的readLine方法
        String line = bufferedReader.readLine();
        if(line != null) {
            String newline = line+";";
            return newline;
        }else {
            return line;
        }    
    }
}

读取文本并显示行数

public class Demo2 {
    public static void main(String[] args) throws IOException {
        //找到目标文件
        File file = new File("D:\新建文件夹\1.txt");
        //建立数据传输通道
        FileReader fileReader = new FileReader(file);
        //读取文本
        BufferedReader bufferedReader = new BufferedReader(fileReader);
        //给读取的文本添加行号
        LineBufferedReader lineBufferedReader= new LineBufferedReader(bufferedReader);
        
        String line = "";
        while((line = lineBufferedReader.readLine())!=null) {
            System.out.println(line);
        }
        bufferedReader.close();
    }
}

读取文本并在每一行后面加一个分号

public class Demo2 {
    public static void main(String[] args) throws IOException {
        //找到目标文件
        File file = new File("D:\新建文件夹\1.txt");
        //建立数据传输通道
        FileReader fileReader = new FileReader(file);
        //读取文本
        BufferedReader bufferedReader = new BufferedReader(fileReader);
        //给读取的文本添加分号
        SemicolonBufferedReader semicolonBufferedReader = new SemicolonBufferedReader(bufferedReader);
        
        String line = "";
        while((line = semicolonBufferedReader.readLine())!=null) {
            System.out.println(line);
        }
        bufferedReader.close();
    }
}

读取文本并显示行数且在每一行后面加一个分号(互相装饰)

public class Demo2 {
    public static void main(String[] args) throws IOException {
        //找到目标文件
        File file = new File("D:\新建文件夹\1.txt");
        //建立数据传输通道
        FileReader fileReader = new FileReader(file);
        //读取文本
        BufferedReader bufferedReader = new BufferedReader(fileReader);
        //给读取的文本添加行号
        LineBufferedReader lineBufferedReader = new LineBufferedReader(bufferedReader);
        //给读取的文本添加分号
        SemicolonBufferedReader semicolonBufferedReader = new SemicolonBufferedReader(lineBufferedReader);
        
        String line = "";
        while((line = semicolonBufferedReader.readLine())!=null) {
            System.out.println(line);
        }
        bufferedReader.close();
    }
}

原文地址:https://www.cnblogs.com/zjdbk/p/9079543.html