「这是我参与2022首次更文挑战的第8天,活动详情查看:2022首次更文挑战」。
序
写了几年的学习笔记,现在终于一个学习周期结束了,开始回顾自己学习过的东西,温故知新的同时复盘下自己的笔记,梳理成博客分享出来。这几年其实浪费了挺多时间的,尤其是21年。不得不说,学习是真的苦且反人类,一直驱动着我学习的无非是对35岁的“焦虑”+对编程一点点的喜欢+对“好”代码的好奇心和憧憬。
我并不身处大厂,也不知大厂的代码是不是想象中那么“完美”。但我知道,我只要不停的追求代码的“完美”,怀着对技术的好奇,我就能一直去探索,那我就不会离的太远·······
代码不是凭一点就能断定好坏的,所以我系统学习了设计模式,从无法理解到推崇,因为我看到了这个代码基建界的瑰宝-设计模式的优雅之处。情怀不必多言,搞的跟鸡汤一样。今天,我来聊聊装饰器模式。
正文
先用最简单的代码讲解下什么是装饰器模式,然后再分析下JDK中的InputStream相关的流是如何使用装饰器模式的(JDK中各种流的实现是装饰器模式经典实现,同时还带有了一点定制的感觉)。
下面先看看装饰器模式的定义,这个模式从名字就能猜出一点东西的。
装饰器模式(Decorator Pattern),向现有对象添加新的功能,同时又不会和原有对象产生耦合。
大家不知道对cos是不是有兴趣,今天让大家过过瘾,我们举个cos的例子。来了,上图~
/**
* 美女
*/
public abstract class Beauty {
public abstract void wearClothes();
}
/**
* 护士美女
*/
public class NurseBeauty extends Beauty {
private final Beauty beauty;
public NurseBeauty(Beauty beauty) {
this.beauty = beauty;
}
@Override
public void wearClothes() {
System.out.println("穿上护士制服");
beauty.wearClothes();
}
}
/**
* 教师制服美女
*/
public class TeacherBeauty extends Beauty {
private String name;
public TeacherBeauty(String name) {
this.name = name;
}
@Override
public void wearClothes() {
System.out.println("这是名为" + name + "的美女,她穿着教师制服");
}
}
/**
* 西装黑丝美女
*/
public class SuitAndBlackSilkBeauty extends Beauty {
private final Beauty beauty;
public SuitAndBlackSilkBeauty(Beauty beauty) {
this.beauty = beauty;
}
@Override
public void wearClothes() {
System.out.println("穿上西装黑丝");
beauty.wearClothes();
}
}
上面有三种类型的美女,她们各有特色,有东方美人的柔情,有西方美女的灵动。。。。扯远了。
她们可以穿各种不同的制服(这就是功能的增强),护士姐姐可以穿上西装黑丝,然后在套上老师的西装外套,想一想~话不多说,让我们看看最后的效果吧!
public class Test {
public static void main(String[] args) {
// 1.原始教师美女
Beauty beauty = new TeacherBeauty("颜如玉");
// 2.穿上黑丝的教师美女
Beauty suitAndBlackSilkBeauty = new SuitAndBlackSilkBeauty(beauty);
// 3.穿上护士服的黑丝教师美女
Beauty nurseBeauty = new NurseBeauty(suitAndBlackSilkBeauty);
nurseBeauty.wearClothes();
}
}
图来~~~~
上面的美女是很漂亮,但是我们身为程序员,要注重的是内在,透过表象看本质,我们来分析下上面的所有代码,Beauty类作为父抽象类,其他不同类型的美女类都实现Beauty类,同时给自己加上‘新功能’,像黑丝美女她就有穿黑丝的‘新功能’。
总结下上面代码的一些特性
1.所有装饰器类(黑丝美女,护士美女)和原始类(教师美女)继承同一个父类(Beauty类)。这样的好处就是不同的装饰器类可以多个叠加嵌套装饰(既是黑丝美女又是护士美女)。
2.修饰器类是对原有功能的增强而非覆盖,这其实是设计思想上的,你硬说非要弄个完全毫无关系的功能也是可以的,代码可以实现,但是这就不存粹了。
3.各个装饰器互相协助是通过组合这种低耦合的方式而非硬性继承,注意这里说的是各个装饰器之间协作,不是装饰器实现的底层接口(类)。
回顾
装饰器模式主要是适合用于那种扩展功能很多的业务场景(可以只发短信,也可以发短信的同时发邮件,也可以发短信和邮件的同时打电话),一般这种场景我们都会存在多层级的继承关系,为了避免继承关系后期的指数性增长和代码的难扩展性,所以我们使用“组合”的方式解耦各个增强的功能点。还有一点就是装饰器模式是对原有功能的增强(像上面说的场景其实就是对通知功能的一种增强)。
求波关注,公众号:java精进天路
有任何问题都可留言哦!