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

1、概述

装饰模式是一种结构型设计模式, 允许你通过将对象放入包含行为的特殊封装对象中来为原对象绑定新的行为。

2、适用场景

1)如果你希望在无需修改代码的情况下即可使用对象, 且希望在运行时为对象新增额外的行为, 可以使用装饰模式。
2)如果用继承来扩展对象行为的方案难以实现或者根本不可行, 你可以使用该模式。

3、实例

有以下场景:

有一套套娃dolls生产线,有生产不同大小的机器。

定义顶层套外抽象接口:

/**
 * 抽象套娃
 * @date: 2021/1/8
 * @author weirx
 * @version 3.0
 */
public interface AbstractDolls {

    int getSize();

    void setSize(int size);
}

套娃实体

/**
 * 套娃实体
 * @date: 2021/1/8
 * @author weirx
 * @version 3.0
 */
public class Dolls implements AbstractDolls{

    public Dolls(int size) {
        this.size = size;
    }

    private int size;

    @Override
    public void setSize(int size) {
        this.size = size;
    }

    @Override
    public int getSize() {
        return this.size;
    }
}

小装饰器:

/**
 * 小装饰器
 * @date: 2021/1/8
 * @author weirx
 * @version 3.0
 */
public class SmallDecorator implements AbstractDolls{

    private AbstractDolls abstractDolls;

    public SmallDecorator(AbstractDolls abstractDolls) {
        this.abstractDolls = abstractDolls;
    }

    @Override
    public int getSize() {
        return abstractDolls.getSize();
    }

    @Override
    public void setSize(int size) {
        abstractDolls.setSize(size);
    }

    public void configSize(){
        this.setSize(this.getSize()+10);
    }
}

中装饰器:

/**
 * 中装饰器
 * @date: 2021/1/8
 * @author weirx
 * @version 3.0
 */
public class MiddleDecorator implements AbstractDolls{

    private AbstractDolls abstractDolls;

    public MiddleDecorator(AbstractDolls abstractDolls) {
        this.abstractDolls = abstractDolls;
    }

    @Override
    public int getSize() {
        return abstractDolls.getSize();
    }

    @Override
    public void setSize(int size) {
        abstractDolls.setSize(size);
    }

    public void configSize(){
        this.setSize(this.getSize()+10);
    }
}

测试类:

import com.cloud.bssp.BsspUserApplication;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

/**
 * test
 * @date: 2020/12/29
 * @author weirx
 * @version 3.0
 */
@RunWith(SpringRunner.class)
@SpringBootTest(classes = BsspUserApplication.class)
public class TestDemo {

    @Test
    public void testDemo() {

        Dolls dolls = new Dolls(10);
        System.out.println("原套娃大小:" + dolls.getSize());
        SmallDecorator smallDecorator = new SmallDecorator(dolls);
        smallDecorator.configSize();
        System.out.println("SmallDecorator装饰后套娃大小:" + dolls.getSize());
        MiddleDecorator middleDecorator = new MiddleDecorator(dolls);
        middleDecorator.configSize();
        System.out.println("MiddleDecorator装饰后套娃大小:" + dolls.getSize());
    }

}

结果:

原套娃大小:10
SmallDecorator装饰后套娃大小:20
MiddleDecorator装饰后套娃大小:30

4、分析

如上所示,在没有修改dolls实体类、且没有继承的情况下完成了对套娃属性的修改。

5、总结

优点:
1)你无需创建新子类即可扩展对象的行为。
2)你可以用多个装饰封装对象来组合几种行为。
3)单一职责原则。 你可以将实现了许多不同行为的一个大类拆分为多个较小的类。
缺点:
1)当多层装饰器嵌套后,比较难删除中间的装饰器。

推荐阅读更多精彩内容