1.9(设计模式)装饰器模式

装饰器模式,主要向一个已有对象添加新的功能。

可以看做对原有对象进行装饰,使其功能更加丰富。

下面就画图举个例子。

Shape接口

public interface Shape {
    public void draw();
}
Rectangle 
public class Rectangle implements Shape{

    @Override
    public void draw() {
        // TODO Auto-generated method stub
        System.out.println("draw rectangle");
    }

}

Circle

public class Circle implements Shape{

    @Override
    public void draw() {
        System.out.println("draw circle");
    }

}

测试

public class Main {
    public static void main(String[] args) {
        Shape circle = new Circle();
        Shape rectangle = new Rectangle();
        circle.draw();
        rectangle.draw();
    }
}
draw circle
draw rectangle

现在我们有了新的要求,画完图形的同时我们需要设置下颜色。

这时我们采用装饰器实现这个功能,在已有对象上添加新功能。

那么首先我们需要创建一个抽象的装饰类,用于装饰Shape,在draw后添加setColor的功能。

既然是对原有对象的扩展,所以我们的抽象装饰类也需要实现Shape接口

public abstract class DecoratorShape implements Shape{
    protected Shape decorator;
    
    public DecoratorShape(Shape decorator) {
        super();
        this.decorator = decorator;
    }

    @Override
    public void draw() {
        // TODO Auto-generated method stub
        decorator.draw();
    }
}

其中  Shape decorator;为被装饰对象,也就是说为decorator提供额外的功能。

具体功能的实现是通过 DecoratorShape 的子类中重写draw方法来实现的。

这里创建了一个 RedDecoratorShape 继承自 DecoratorShape,用于为图像设置红色。

同时draw中通过 decorator调用了Shape接口中图像原有的draw方法,原有的画图方法没有被改变,

只是在画图之后添加了设置颜色的方法 setRed。 

public class RedDecoratorShape extends DecoratorShape{

    public RedDecoratorShape(Shape decorator) {
        super(decorator);
        // TODO Auto-generated constructor stub
    }

    @Override
    public void draw() {
        decorator.draw();//decorator的访问级别为protected,子类可以访问。
        setRedShape();
    }
    
    private void setRedShape() {
        System.out.println("color : red");
    }
}

测试

public class Main {
    public static void main(String[] args) {
        //图形
        Shape circle = new Circle();
        Shape rectangle = new Rectangle();
        //红色装饰器,为图像添加设置颜色的功能
        DecoratorShape redCircle = new RedDecoratorShape(circle);
        DecoratorShape redRectangle = new RedDecoratorShape(rectangle);
        //绘图同时设置颜色
        redCircle.draw();
        redRectangle.draw();
    }
}
draw circle
color : red
draw rectangle
color : red

如果我们现在想图像上既有红色又有蓝色,这时我们只需要在写一个BlueDecoratorShape,同时使用它装饰redCircle即可

BlueDecoratorShape

public class BlueDecoratorShape extends DecoratorShape{
    
        
    public BlueDecoratorShape(Shape decorator) {
        super(decorator);
        // TODO Auto-generated constructor stub
    }

    @Override
    public void draw() {
        decorator.draw();
        setRedShape();
    }
    
    private void setRedShape() {
        System.out.println("color : blue");
    }
    
}

Main

public class Main {
    public static void main(String[] args) {
        
        //图形
        Shape circle = new Circle();
        Shape rectangle = new Rectangle();
        //红色装饰器,为图像添加设置颜色的功能
        DecoratorShape redCircle = new RedDecoratorShape(circle);
        DecoratorShape redRectangle = new RedDecoratorShape(rectangle);
        //在图像的基础上装饰了红色
        redCircle.draw();
        redRectangle.draw();
        
        System.out.println();
        
        //在红色图像的基础上装饰了蓝色
        DecoratorShape buleRedCircle = new BlueDecoratorShape(redCircle);
        DecoratorShape blueRedRectangle = new BlueDecoratorShape(redRectangle);
        buleRedCircle.draw();
        blueRedRectangle.draw();
        
    }
}
运行结果:
draw circle color : red draw rectangle color : red draw circle color : red color : blue draw rectangle color : red color : blue

装饰模式注重在对原有功能的扩展增强,后续需要多种颜色还可以继续装饰下去。

参考资料:

https://www.runoob.com/design-pattern/decorator-pattern.html

原文地址:https://www.cnblogs.com/huang-changfan/p/10960015.html