# 装饰器模式

## 概念

动态地给一个对象添加一些额外的职责。 就增加功能来说,装饰模式相比生成子类更为灵活

## 代码

* Component抽象构件

Component是一个`接口`或者是`抽象类`,就是定义我们最核心的对象,也就是最原始的对象,

```java
public abstract class Component {
    public abstract void test();
    public abstract void test2();

}
```

* ConcreteComponent 具体构件

最核心、最原始、最基本的接口或抽象类的实现,你要装饰的就是他

```java
public class ConcreteComponent extends Component {
    public void test() {
        System.out.println("实现 test");
    }

    public void test2() {
        System.out.println("实现 test2");

    }
}
```

* Decorator装饰角色

实现接口或者抽象方法,它里面可不一定有抽象的方 法呀,在它的属性里必然有一个private变量指向Component抽象构件

```java
public abstract class Decorator extends Component {
    private Component component;
    // 通过构造函数传递被修饰着
    public Decorator(Component component) {
        this.component = component;
    }

    public void test() {
        component.test();
    }

    public void test2() {
        component.test2();
    }
}
```

* 具体装饰角色

```java
public class ConcreteDecorator1 extends Decorator {
    // 定义被修饰着
    public ConcreteDecorator1(Component component) {
        super(component);
    }

    @Override
    public void test() {
        doSomething();
        super.test();

    }

    @Override
    public void test2() {
        super.test2();
        doAnything();
    }
    // 修饰方法
    public void doSomething() {
        System.out.println("do something");
    }

    public void doAnything() {
        System.out.println("do Anything");
    }


}
/**
 * @Author: small_double
 * @Date: 2019/9/24 下午3:54
 */
public class ConcreteDecorator2 extends Decorator {

    public ConcreteDecorator2(Component component) {
        super(component);
    }

    @Override
    public void test() {
        super.test();
        this.method2();
    }

    @Override
    public void test2() {
        super.test2();
    }

    void method2() {
        System.out.println("decorator2");
    }
}
```

* 调用

  ```java
  /**
  * @Author: small_double
  * @Date: 2019/9/24 下午3:55
  */
  public class Client {
    public static void main(String[] args) {
        Component component = new ConcreteComponent();
        // 第一次修饰
        component = new ConcreteDecorator1(component);
         // 第二次修饰
        component = new ConcreteDecorator2(component);

        component.test();

        component.test2();

    }
  }
  ```
