装饰器模式(Java)

装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。

该设计模式是使用组合替代继承的具体实现。

使用装饰器模式

不修改图形绘制类的情况下增加绘制颜色的功能

/*
 * 绘制图形
 */ 
interface Shape {
    void draw();
}

class Rectangle implements Shape {
    @Override
    public void draw() {
        System.out.println("绘制长方形");
    }
}

class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("绘制圆");
    }
}

/*
 * 绘制图形颜色
 */
class RedShape implements Shape {

    private Shape shape;

    public RedShape(Shape shape) {
        this.shape = shape;
    }

    @Override
    public void draw() {
        this.shape.draw();
        setRedBorder();
    }

    private void setRedBorder(){
        System.out.println("使图形颜色为红色");
    }

}

class YellowShape implements Shape {

    private Shape shape;

    public YellowShape(Shape shape) {
        this.shape = shape;
    }

    @Override
    public void draw() {
        this.shape.draw();
        setRedBorder();
    }

    private void setRedBorder(){
        System.out.println("使图形颜色为黄色");
    }

}

class ShapeTest {
    public static void main(String[] args) {
        Shape redCircle = new RedShape(new Circle());
        Shape redRectangle = new RedShape(new Rectangle());
        redCircle.draw();
        redRectangle.draw();

        System.out.println();

        Shape yellowCircle = new YellowShape(new Circle());
        Shape yellowRectangle = new YellowShape(new Rectangle());
        yellowCircle.draw();
        yellowRectangle.draw();

    }
}

装饰器模式在Java IO类中的使用

//文件字节流读取类
InputStream in = new FileInputStream("./test.txt");

//在不修改FileInputStream的情况下,给FileInputStream增加缓存功能
InputStream bin = new BufferedInputStream(in);

//在不修改FileInputStream的情况下,让FileInputStream支持按照基本数据类型来读取数据,例如int, boolean, long等
InputStream din = new DataInputStream(in);

//还有其他的这里就不一一列举了。。。。

试想一下,如果不使用组合而是使用继承,有的子类增强一个功能,有的子类可能需要增强多个功能,这样的话就需要派生出很多子类,类的继承机构将会变得无比复杂,代码及不好扩展也不好维护。

总结

装饰器模式主要解决继承关系过于复杂得问题,通过组合代替继承。

上一篇:杭电OJ第11页2045~2049算法题(C语言)


下一篇:在C#中使用OpenCV(使用GOCW)