装饰模式(Decorator Pattern)- 最通俗易懂的案例
创作时间:
作者:
@小白创作中心
装饰模式(Decorator Pattern)- 最通俗易懂的案例
引用
CSDN
1.
https://blog.csdn.net/weixin_39296283/article/details/104970189
装饰模式(Decorator Pattern)是一种结构型设计模式,它允许在运行时动态地给对象添加新的功能。与继承相比,装饰模式更加灵活,可以避免类爆炸的问题。本文将通过一个通俗易懂的案例,详细介绍装饰模式的概念、结构和实现。
前言
在软件开发中,我们常常需要扩展一个类的功能。传统的做法是通过继承来实现,但这种方法存在一些缺点,比如单继承的局限性和可能产生类爆炸的后果。装饰模式(Decorator)提供了一种更灵活的解决方案,它可以在不改变原有类结构的情况下,动态地给对象添加新的功能。
装饰模式属于结构型模式,它的核心思想是将对象包装在装饰器中,通过装饰器来扩展对象的功能。被装饰的对象和装饰器之间不需要相互了解,这使得它们可以独立发展,互不影响。
结构模式图
- Component:定义一个对象接口,可以给这些对象动态地添加职责。
- ConcreteComponent:定义了一个具体的对象,也可以给这个对象添加一些职责。
- Decorator:装饰抽象类,继承了 Component,从外类来扩展Component的功能,但对于Component来说,是无需知道Decorator的存在的。
- ConcreteDecoratorA/B:具体的装饰对象,起到给Component添加职责的功能。
案例实现
想象一下这个情景:清晨上班的你在路上遇到一家面馆,你便进去点了一碗面吃,然后你又发现菜单栏上有许多的配料:牛肉、荷包蛋、鸡腿,这时你看到旁边的一个老板把这三个全部点了一遍加到他的面里,于是你也不甘示弱,但作为程序员的你只加了一个荷包蛋进去。
现在我们用装饰模式来完成上面这个需求:往面条里面加配料。
定义对象接口
package com.design_pattern.decorator;
public interface INoodles {
public void cook();
}
具体实现类
package com.design_pattern.decorator;
public class Noodles implements INoodles {
@Override
public void cook() {
System.out.println("的面条");
}
}
抽象装饰类
package com.design_pattern.decorator;
public abstract class NoodlesDecorator implements INoodles {
private INoodles noodles; //添加一个INoodles 的引用
public NoodlesDecorator(INoodles noodles){ //通过构造器来设置INoodles
this.noodles = noodles;
}
@Override
public void cook() {
if (noodles!=null){
noodles.cook();
}
}
}
具体装饰类
EggDecorator
package com.design_pattern.decorator;
public class EggDecorator extends NoodlesDecorator {
public EggDecorator(INoodles noodles) {
super(noodles);
}
@Override
public void cook() {
System.out.println("加了一个荷包蛋");
super.cook();
}
}
BeefDecorator
package com.design_pattern.decorator;
public class BeefDecorator extends NoodlesDecorator {
public BeefDecorator(INoodles noodles) {
super(noodles);
}
@Override
public void cook() {
System.out.println("加了一斤牛肉");
super.cook();
}
}
ChickenLegDecorator
package com.design_pattern.decorator;
public class ChickenLegDecorator extends NoodlesDecorator {
public ChickenLegDecorator(INoodles noodles) {
super(noodles);
}
@Override
public void cook() {
System.out.println("加了一个鸡腿");
super.cook();
}
}
客户端代码
package com.design_pattern.decorator;
public class Client {
public static void main(String[] args) {
//一位老板来了说我全要
INoodles noodles = new Noodles();
INoodles noodlesWithEgg = new EggDecorator(noodles);
INoodles noodlesWithEggAndChickenLeg = new ChickenLegDecorator(noodlesWithEgg);
INoodles noodlesWithEggAndChickenLegAndBeef = new BeefDecorator(noodlesWithEggAndChickenLeg);
noodlesWithEggAndChickenLegAndBeef.cook();
System.out.println("************分割线**************");
//咱是程序员,咱加一个蛋就行了
INoodles noodles1 = new Noodles();
INoodles noodles1WithEgg = new EggDecorator(noodles1);
noodles1WithEgg.cook();
}
}
打印输出:
加了一斤牛肉
加了一个鸡腿
加了一个荷包蛋
的面条
************分割线**************
加了一个荷包蛋
的面条
总结
优缺点分析
优点:
- 装饰类和被装饰类可以独立发展,不会相互耦合。
- 装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。
缺点:
- 多层装饰比较复杂。
使用场合
- 如果你希望在无需修改代码的情况下即可使用对象,且希望在运行时为对象新增额外的行为,可以使用装饰模式。
- 如果用继承来扩展对象行为的方案难以实现或者根本不可行,你可以使用该模式。
热门推荐
中考冲刺:应对考试焦虑的五大策略
《原神》茜特菈莉技能解析与出装培养讲解 茜特菈莉有什么技能
《邮差》:一部对人性、社会,以及沟通深刻思考的电影
风水与堪虞:传统智慧与当代生活的结合
占星学,星座运势和生辰八字的区别
小心!赶海真的会让人无法自“拔”
汉武帝刘彻有哪些成就?他留下了哪些文学作品?
美白牙膏真的能让牙齿变白吗?对于外源性污渍可能会有一定的作用
英国伯明翰经济收入现状与未来展望
4种脂溶性维生素的常见缺乏症与补充!
掌握深度思考14个核心要素:帮你解锁高效思维与最优行动的路径!
婚姻计划是什么
充满噪音的世界如何严重损害我们的健康?
第一狂战士卡赞蝰蛇打法技巧
适合女孩子的12画字取名推荐与解析
冲锋衣尺码抉择:偏大还是合身?
走食神大运特征解析及其影响
《三块广告牌》:通过色彩语言和情感表达,看电影艺术的独特表现
广州白云机场过夜攻略:休息区设施全解析
广州白云机场过夜攻略
关于《苏州河》重要道具线索的解读
研究表明,豆浆可以降低患心脏病的风险因素
骨髓水肿怎么消退
膝盖疼痛,深入了解相关原因及对策
老房子2平米卫生间改造,空间小也能装出高级感!
又到青梅煮酒时,以十首有关青梅的诗词,来迎接芒种节气!
宁夏:瞄准养生新赛道 开发枸杞产品120余款
关于二手DIY 你需要避开的那些晦暗深坑!
B2首飞已有30多年,依旧是世界最强隐形战略轰炸机!
怀孕期间使用 Calonal 安全吗?检查你的医生的建议