装饰器模式及JAVA IO流例子★★★☆☆

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了装饰器模式及JAVA IO流例子★★★☆☆相关的知识,希望对你有一定的参考价值。

一、什么是装饰模式

通过关联机制给类增加行为,其行为的扩展由修饰对象来决定;

二、补充说明

与继承相似,不同点在于继承是在编译期间扩展父类,而装饰器模式在运行期间动态扩展原有对象;

或者说,继承是对类进行扩展,装饰模式是对对象进行扩展;

三、角色

抽象构件

具体构件

抽象装饰类

具体装饰类

说明:具体构件、抽象装饰类、具体装饰类的共同父类是抽象构件,具体装饰类继承抽象装饰类并在运行期间装饰具体构件;

四、例子

例子说明:

画家接口Painter,为抽象构件,有两个方法,获取画家描述信息及绘画;

PaintBeginner实现Painter接口,为具体构件;

PainterDecorator实现Painter接口,为抽象装饰类,其内部关联一个Painter对象,通过构造函数获取;

HillPainterDecorator、RiverPainterDecorator、TreePainterDecorator为具体装饰类,表明被装饰的画家能够绘画Hill、River、Tree;

类图:

技术分享

代码实现:

Painter.java

技术分享
package com.pichen.dp.decorator;

public interface Painter {


    public abstract String getDescription();
    
    public abstract String painting();
    
}
View Code

PaintBeginner.java

技术分享
package com.pichen.dp.decorator;

public class PaintBeginner implements Painter{

    @Override
    public String getDescription() {

        return "";
    }

    @Override
    public String painting() {
        /* do nothing */
        return "";
    }

}
View Code

PainterDecorator.java

技术分享
package com.pichen.dp.decorator;

public abstract class PainterDecorator implements Painter{

    private Painter decoratedPainter;
    public PainterDecorator(Painter decoratedPainter) {
        this.decoratedPainter = decoratedPainter;
    }
    
    public Painter getPainter(){
        return this.decoratedPainter;
    }
}
View Code

HillPainterDecorator.java

技术分享
package com.pichen.dp.decorator;

public class HillPainterDecorator extends PainterDecorator{

    public HillPainterDecorator(Painter paper) {
        super(paper);
    }

    
    
    @Override
    public String getDescription() {
        return this.getPainter().getDescription() + "can paint hill, ";
    }

    @Override
    public String painting() {
        /* painting the hill */
        return this.getPainter().painting() + paintingHill();
    }
    
    public String paintingHill(){
        return "Hill, ";
    }

}
View Code

RiverPainterDecorator.java

技术分享
package com.pichen.dp.decorator;

public class RiverPainterDecorator extends PainterDecorator{

    public RiverPainterDecorator(Painter paper) {
        super(paper);
    }

    @Override
    public String getDescription() {
        return this.getPainter().getDescription() + "can paint river, ";
    }

    @Override
    public String painting() {

        /* painting the river */
        return this.getPainter().painting() + paintingRiver();
    }
    
    public String paintingRiver(){
        return "River, ";
    }

}
View Code

TreePainterDecorator.java

技术分享
package com.pichen.dp.decorator;

public class TreePainterDecorator extends PainterDecorator{

    public TreePainterDecorator(Painter paper) {
        super(paper);
    }

    @Override
    public String getDescription() {
        return this.getPainter().getDescription() + "can paint tree, ";
    }

    @Override
    public String painting() {
        /* painting the tree */
        return this.getPainter().painting() + paintingTree();
    }
    
    public String paintingTree(){
        return "Tree, ";
    }

}
View Code

Main.java

package com.pichen.dp.decorator;

public class Main {

    public static void main(String[] args) {
        
        Painter p0 = new PaintBeginner();
        System.out.println("Painter description:" + p0.getDescription());
        System.out.println("Painting:" + p0.painting() + "\\n");

        Painter p1 = new HillPainterDecorator(new RiverPainterDecorator(new TreePainterDecorator(new PaintBeginner())));
        System.out.println("Painter description:" + p1.getDescription());
        System.out.println("Painting:" + p1.painting() + "\\n");
        
        
        Painter p2 = new RiverPainterDecorator(new HillPainterDecorator(new PaintBeginner()));
        System.out.println("Painter description:" + p2.getDescription());
        System.out.println("Painting:" + p2.painting() + "\\n");
    }

}

执行结果如下,PaintBeginner类的对象未装饰前,无行为;在被装饰器装饰后,其行为可动态扩展:

技术分享

五、JAVA IO流与装饰模式

这里简单的以Reader、BufferedReader、FileReader举个例子,如下代码:

        BufferedReader br = new BufferedReader(new FileReader(new File("test.txt")));
        br.readLine();

说明:

其中BufferedReader与BufferedReader有一个共同抽象父类Reader,Reader为抽象构件;

new FileReader(new File("test.txt"))为具体构件,运行期间被修饰的对象;

BufferedReader为具体修饰类,运行期间修饰具体构件;

装饰后,被修饰的对象新增的行为是拥有readLine方法;

ps:查看源码,没发现BufferedReader对应的抽象装饰类,个人觉得没有抽象装饰类,装饰模式也是可以正常工作的,抽象构件(Reader)可以由具体修饰类关联;

另外,具体修饰类也可以作为基类,被其它类继承的,继承后的类同样也是具体修饰类,如LineNumberReader就是继承BufferedReader;

所以,上面语句还可以这样写(ps:只是举例,其实没必要用BufferedReader修饰,直接LineNumberReader装饰下就可以):

        BufferedReader br = new LineNumberReader(new BufferedReader(new FileReader(new File("test.txt"))));
        br.readLine();

links:

装饰器模式★★★☆☆

生成器or建造者模式★★☆☆☆

抽象工厂模式★★★★★

工厂方法模式★★★★★

简单工厂模式★★★★☆

以上是关于装饰器模式及JAVA IO流例子★★★☆☆的主要内容,如果未能解决你的问题,请参考以下文章

java 装饰着模式,谁能给我说明一下,谢谢了

10.9-全栈Java笔记:装饰器模式构建IO流体系

java _io_字节缓冲流(装饰器)输入输出

java IO包装流如何关闭

装饰器模式

java----IO