装饰器模式

88 阅读2分钟

1、定义一个形状接口

package decorator;

public interface Shape {
    void draw();
}

2、定义一个正方形和圆形的类实现形状接口

package decorator;

public class Square implements Shape {
    @Override
    public void draw() {
        System.out.println("Shape:Square");
    }
}
package decorator;

public class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("Shape:circle");
    }
}

3、测试

package decorator;

public class Test {

    public static void main(String[] args) {
        Shape circle = new Circle();
        Square square = new Square();
        circle.draw();
        square.draw();
    }

}

输出

Shape:circle
Shape:Square

4、创建一个抽象的装饰器,实现被装饰对象的接口

package decorator;

public abstract class ShapeDecorator implements Shape {

    protected Shape decoratorShape;

    public ShapeDecorator(Shape decoratorShape) {
        this.decoratorShape = decoratorShape;
    }

    @Override
    public void draw() {
        decoratorShape.draw();
    }
}

为什么要定义成抽象的,非抽象的也完全ok。后面再说

5、具体的加入新功能的装饰器实现类,加个红色。

package decorator;

public class RedShapeDecorator extends ShapeDecorator {

    public RedShapeDecorator(Shape decoratorShape) {
        super(decoratorShape);
    }

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

    private void setRedBorder(Shape decoratorShape) {
        System.out.println("Border Color:Red");
    }

}

6、测试

package decorator;

public class Test {

    public static void main(String[] args) {
        Shape redCircle2 = new RedShapeDecorator(new Circle());
        Shape redSquare2 = new RedShapeDecorator(new Square());

        redCircle2.draw();
        redSquare2.draw();
    }
}

输出

Shape:circle
Border Color:Red
Shape:Square
Border Color:Red

7、为什么为什么要定义成抽象的,非抽象的也完全ok。

现在要进行扩展,接口加两个方法。

package decorator;

public interface Shape {

    void draw();

    void draw1();

    void draw2();
}

正方形实现类

package decorator;

public class Square implements Shape {
    @Override
    public void draw() {
        System.out.println("Shape:Square");
    }

    @Override
    public void draw1() {
        System.out.println("Shape:Square1");
    }

    @Override
    public void draw2() {
        System.out.println("Shape:Square2");
    }
}

圆形实现类

public class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("Shape:circle");
    }

    @Override
    public void draw1() {
        System.out.println("Shape:circle1");
    }

    @Override
    public void draw2() {
        System.out.println("Shape:circle2");
    }
}

1)抽象包装类

抽象的装饰器

package decorator;

public abstract class ShapeDecorator implements Shape {

    protected Shape decoratorShape;

    public ShapeDecorator(Shape decoratorShape) {
        this.decoratorShape = decoratorShape;
    }

    @Override
    public void draw() {
        decoratorShape.draw();
    }

    @Override
    public void draw1() {
        decoratorShape.draw1();
    }

    @Override
    public void draw2() {
        decoratorShape.draw2();
    }
}

装饰器的具体实现类

package decorator;

public class RedShapeDecorator extends ShapeDecorator {

    public RedShapeDecorator(Shape decoratorShape) {
        super(decoratorShape);
    }

    // 这个类只想增强一下draw()方法,不想变动其他的f1,f2方法,所以这个类只需要重写这个类即可
    @Override
    public void draw() {
        decoratorShape.draw();
        setRedBorder(decoratorShape);
    }

    private void setRedBorder(Shape decoratorShape) {
        System.out.println("Border Color:Red");
    }

}

2)非抽象装饰器

package decorator;

public class GreenShapeDecorator implements Shape {

    protected Shape decoratorShape;

    public GreenShapeDecorator(Shape decoratorShape) {
        this.decoratorShape = decoratorShape;
    }

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

    private void setRedBorder(Shape decoratorShape) {
        System.out.println("Border Color:Green");
    }

    //这个类仅仅想增强draw方法,但是因为实现的是顶层接口,不得不重写这个方法
    @Override
    public void draw1() {
        decoratorShape.draw1();
    }

    //这个类仅仅想增强draw方法,但是因为实现的是顶层接口,不得不重写这个方法
    @Override
    public void draw2() {
        decoratorShape.draw2();
    }
}

3)总结

使用抽象类实现可以只重写想要增强的方法,不用实现其它。