装饰者模式是一种结构型模式 可以动态地给一个对象添加功能 这些功能也可以动态地被撤销

    装饰者模式用到的设计原则:
    1)多用组合 少用继承
    2)开闭原则(对拓展开放 对修改关闭)

    优点:
    装饰者模式相比于继承更灵活 可以动态的为对象添加功能

    缺点:
    多层装饰时比较复杂 出错之后调试起来比较麻烦

    装饰者模式实现步骤:
    1)先定义一个顶级抽象类/接口 为了给对象动态地添加功能/职责

    其中被装饰类也就是实际被动态添加功能的类 要继承/实现这个抽象类或接口
    2)再定义一个抽象类 也去继承/实现上述抽象类或接口 是为了扩展顶级抽象类或接口的功能的
    3)最后就是定义具体的装饰类了 这个类就是给被装饰类动态添加功能的
    在类中将顶级接口作为属性 通过构造方法传入为其赋值
    然后在这个类下就可以使用到被装饰类的方法 也可以定义新的功能
    ee8ddb926d0ac403002f937c0bb3f1d.png
    如下案例:
    有一个男人 什么都没有 经过装饰 可以有车 有房
    顶级接口:

    1. package decorator;
    2. /**
    3. * 顶级的接口 目的是为了让被装饰对象的方法 和 Decorator 的方法名字统一
    4. * 统一了以后 用户就分不清了 用起来方便些
    5. */
    6. public interface Top {
    7. String getAssets();
    8. }

    Man类(原始对象):

    1. package decorator;
    2. /**
    3. * 原始对象
    4. */
    5. public class Man implements Top{
    6. private String name;
    7. public Man(String name){
    8. this.name = name;
    9. }
    10. public Man(){}
    11. public String getAssets(){
    12. return "我的名字是"+name+",我是一个男人,但我现在什么都没有!";
    13. }
    14. }

    抽象的装饰者:

    1. package decorator;
    2. /**
    3. * 定义装饰者规则
    4. * 这个类的目的是为了装饰时可以随意的进行装配
    5. * 而不是需要按照某种顺序一层一层的装饰
    6. */
    7. public abstract class Decorator implements Top{
    8. //因为具体装饰类都会用到top对象中的方法
    9. //所以可以将其从具体类中抽离出来 放到这个类中 减少代码的冗余
    10. protected Top top;
    11. public Decorator(Top top){
    12. this.top = top;
    13. }
    14. public abstract String getAssets();
    15. }

    具体装饰者1:

    1. package decorator;
    2. public class BuyCar extends Decorator{
    3. public BuyCar(Top top){
    4. super(top);
    5. }
    6. public String getAssets(){
    7. //先获取被装饰类的结果
    8. String msg = top.getAssets();
    9. return msg+"经过努力,我有车了!";
    10. }
    11. }

    具体装饰者2:

    1. package decorator;
    2. public class BuyHouse extends Decorator{
    3. public BuyHouse(Top top){
    4. //传递的参数是顶级接口
    5. //所以此时参数就可以随便传 随意装饰
    6. //而不是必须要按照某种顺序来进行装饰
    7. super(top);
    8. }
    9. public String getAssets(){
    10. //先获取被装饰类的结果
    11. String msg = top.getAssets();
    12. return msg+"经过努力,我有房了!";
    13. }
    14. }