天天看点

Java设计模式之装饰器模式(Decorator Pattern)

Java设计模式之装饰器模式

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

在编写代码过程中我们想要扩展一个实体类的功能时(AOP这里不讨论)并且要保证OCP原则(一个软件实体如类,模块和函数应该对扩展开放,对修改关闭)下一般会选择去重写一个类继承当前的类,然后新增加需要的方法。在一般情况下这个当然没问题,但是如果造成一些问题,就是以后每次想要扩展新的功能都必须要新增一个类,这样长此以往的话会造成类过多,并且不能进行随意搭配想要的新功能,在排列组合中假设我们要新增K个功能,然后需要每N个功能相组合如果采用继承的话会产生 C k n C_{k}^{n} Ckn​个类,可想而知这不是一个很有成效的办法。

装饰器模式

优点:装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。

缺点:多层装饰比较复杂,可读性比较差。

实现

我们将创建一个 Shape 接口和实现了 Shape 接口的实体类。然后我们创建一个实现了 Shape 接口的抽象装饰类 ShapeDecorator,并把 Shape 对象作为它的实例变量。

RedShapeDecorator 是实现了 ShapeDecorator 的实体类。

接下来我们模仿菜鸟教程中的教程演示类使用 RedShapeDecorator 来装饰 Shape 对象。

下面我们就直接上代码啦

下面展示一些

内联代码片

最顶层的抽象类“Shape”

package com.meking.decorator;

public interface Shape {

    void draw();
}
           

“Shape”下面的实现“Rectangle”

package com.meking.decorator;

public class Rectangle implements Shape {
    @Override
    public void draw() {
        System.out.println("Rectangle:绘制功能");
    }
}
           

“Shape”下面的实现“Circle”

package com.meking.decorator;

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

抽象的装饰器“ShapeDecorator ”

package com.meking.decorator;

public abstract class ShapeDecorator implements Shape {
    private Shape shape;

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

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

具体的装饰器实现类“RedShapeDecorator”

package com.meking.decorator;

public class RedShapeDecorator extends ShapeDecorator {

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

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

    /**
     * 设置红色边界的方法
     */

    private void setRedBorder(){
        System.out.println("设置红色边界");
    }

           

测试

package com.meking.decorator;

public class DecoratorPatternTest {

    public static void main(String[] args) {
        new RedShapeDecorator(new Rectangle()).draw();
        new RedShapeDecorator(new Circle()).draw();
    }
}
           

结果

Java设计模式之装饰器模式(Decorator Pattern)

以上就是我们的测试结果,在装饰模式中我们可以随意搭配需要装饰什么,只需要实现多个不同的装饰器就行了,接下面我们在对功能进行增强。

具体的装饰器实现类“PaddingShapeDecorator”

package com.meking.decorator;

public class PaddingShapeDecorator extends ShapeDecorator  {

    public PaddingShapeDecorator(Shape shape) {
        super(shape);
    }

    @Override
    public void draw() {
        super.draw();
        setPadding();
    }

    /**
     * 设置填充图案的方法
     */

    private void setPadding(){
        System.out.println("设置图案填充");
    }
}
           

测试

package com.meking.decorator;

public class DecoratorPatternTest {

    public static void main(String[] args) {
        //Rectangle设置红色边框
        new RedShapeDecorator(new Rectangle()).draw();
        System.out.println("-------------11---------------");
        //Circl设置红色边框
        new RedShapeDecorator(new Circle()).draw();
        System.out.println("-------------22---------------");
        //Rectangle设置红色边框并且填图案
        new PaddingShapeDecorator(new RedShapeDecorator(new Rectangle())).draw();
        System.out.println("-------------33---------------");
        //Circle设置红色边框并且填图案
        new PaddingShapeDecorator(new RedShapeDecorator(new Circle())).draw();
        System.out.println("-------------44---------------");
        //Rectangle只进行填充
        new PaddingShapeDecorator(new Rectangle()).draw();
    }
}
           

结果

Java设计模式之装饰器模式(Decorator Pattern)

总结

装饰器模式是可以随意灵活的进行各种搭配,有效的避开了因为需要各种不同的组合产生太多的继承类这个问题,有不对之处也请各位同学及时指正,有问题的也请各位同学在评论处进行总结。