设计模式——装饰者模式

660 阅读3分钟
什么是装饰者模式?

装饰者模式属于结构型模式。目的是为了扩展对象的功能,通过持有对象的引用,把对象包装起来,可以在调用对象的方法之前或者之后增加新的功能,以达到给对象添加一些额外的功能,这种操作被称之为装饰。装饰者可以有多个,对象被包装了一层之后,可以继续再次包装来增加新的功能,目的就是为了扩展对象的功能。可以使得系统具备非常好的弹性,遵循了面向对象的原则:对扩展开放,对修改关闭。如果有新需求的变更,对象功能扩展,只需要增加一个装饰者类,将对象包装起来即可扩展对象的功能,而不需要对旧的原对象代码进行修改。

通过继承,子类进行方法重写同样也可以扩展对象的功能,但是弹性比较差,一旦业务变更或新增业务功能时,就需要打开实现类的代码进行修改,既要检查旧代码,又要保证新增代码的正确性。类的继承关系是在编译期就已经确定的,运行期间不能动态的更改,使用装饰者模式可以在运行期间动态的,不限量的给对象添加装饰者,扩展功能。装饰者模式是替代继承来扩展对象功能更好的方案。

举个例子?

举个例子 1)创建一个接口

public interface Shape {
    
    void draw();
}

2)创建实现接口的实体类

public class Rectangle implements Shape {

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

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

3)创建实现了Shape接口的抽象装饰类

public abstract class ShapeDecorator implements Shape {

    protected Shape decoratedShape;

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

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

4)创建扩展了ShapeDecorator类的实体装饰类

public class RedShapeDecorator extends ShapeDecorator {

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

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

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

5)使用RedShapeDecorator来装饰Shape对象

public static void main(String[] args) {
    Shape circle = new Circle();
    ShapeDecorator redCircle = new RedShapeDecorator(new Circle());
    ShapeDecorator redRectangle = new RedShapeDecorator(new Rectangle());
    System.out.println("Circle with normal border");
    circle.draw();

    System.out.println("\nCircle of red border");
    redCircle.draw();

    System.out.println("\nRectangle of red border");
    redRectangle.draw();
}

6)控制台输出结果

控制台输出结果

总结

装饰者模式涉及四个角色:Component:组件对象的抽象接口,可以给这些对象动态的增加职责/功能,上面例子中的Shape接口;ConcreteComponent:具体的组件的对象,实现组件对象的接口,是被装饰器装饰的原始对象,即可以给这个对象动态的添加职责,上面例子中的Circle和Rectangle;Decorator:所有装饰器的抽象父类,实现了组件对象的接口,并且持有一个组件对象(被装饰的对象),上面例子中的ShapeDecorator;ConcreteDecorator:具体的装饰器,具体实现向装饰对象添加功能,上面例子中的RedShapeDecorator。注意装饰者模式仅增强功能,不改变接口,本质是动态组合。