白话装饰器模式

装饰器模式(Decorator Pattern)提供了一种给对象灵活地、动态地添加额外功能的思路,装饰器模式是一种结构型模式。

日常开发中,经常需要对一个旧的类进行扩展,但是又希望遵循开闭原则不直接修改原本的类,于是我们可以创建一个子类并继承原类,并进行新增或者重写。如果扩展的次数不多,采用这种方式就可以方便快捷的完成扩展。

但是这种继承的方式是静态的,会随着扩展次数的增多,子类越来越多的同时继承关系越来越复杂,并且不同版本之间的类严重耦合。

经验和直觉告诉我们应该可以在 原有类扩展 之间增加一层东西,从而降低上述的耦合。

这层东西,就是装饰器(Decorator),它可以抽象的理解成套在被装饰类外面的一层壳子,可以在这层壳子上增加各种装饰,从而达到扩展被装饰类的效果。

装饰器模式,相较于上面继承方法,是一种动态的扩展,耦合度大大降低,装饰类和被装饰类可以各自发展。

正文

LOL 中有不同的英雄,英雄都可以看做是被装饰类;每个英雄可以买不同的装备,装备可以看作是装饰。下面依据这种概念来进行举例:

wabsv6.png

实现,英雄(被装饰类)接口:

//英雄接口
public interface Hero {
    //攻击力
    Integer showAttackPower();
    //背包中的装备
    String showBackpack();
}

英雄(被装饰类)实现:

//实现两个英雄:提莫和辛德拉
public class Timo implements Hero {
    @Override
    public Integer showAttackPower() {
        return 55;
    }
    @Override
    public String showBackpack() {
        return "腐败药水";
    }
}
public class Sindra implements Hero {
    @Override
    public Integer showAttackPower() {
        return 53;
    }

    @Override
    public String showBackpack() {
        return "多兰两红";
    }
}

装饰器:

//装饰器
public abstract class Decorator implements Hero {
    private Hero hero;
    //通过构造方法传入被装饰类
    public Decorator(Hero hero) {
        this.hero = hero;
    }

    @Override
    public Integer showAttackPower() {
        return hero.showAttackPower();
    }

    @Override
    public String showBackpack() {
        return hero.showBackpack();
    }
}

装备(装饰类)实现:

//实现两个装备:帽子和面具
public class Hat extends Decorator {
    public Hat(Hero hero) {
        super(hero);
    }

    @Override
    public Integer showAttackPower() {
        return super.showAttackPower() + 80;
    }

    @Override
    public String showBackpack() {
        return super.showBackpack() + "、大帽子";
    }
}
public class Mask extends Decorator {
    public Mask(Hero hero) {
        super(hero);
    }

    @Override
    public Integer showAttackPower() {
        return super.showAttackPower() + 60;
    }

    @Override
    public String showBackpack() {
        return super.showBackpack() + "、大面具";
    }
}

看一下 IDEA 生成的类图:

wwMKW4.png

照例,依然是找一个 JDK 中装饰器模式的应用,IO 包中的输入流就是使用了装饰器模式,来看类图:

wwMuYF.png

输入流有多个子类:文件输入流、字节输入流等等。。同时还有一个装饰器(过滤输入流),同时有多个子装饰器:加校验、加缓存等等。。使用的方法:

public static void main(String[] args) {
    try {
        InputStream inputStream = new FileInputStream("src/main/Decorator.java");
        inputStream = new BufferedInputStream(inputStream);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
}

装饰器模式在实际应用中还是有一定的难度的,需要结合需求灵活选择。装饰器模式的中心思想就是提供一种继承之外的方式,进而降低耦合,实现更加清晰地职责划分。


菜鸟本菜,不吝赐教,感激不尽!

更多题解源码和学习笔记:githubCSDNM1ng

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值