装饰模式(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();
}
}
打印输出:
加了一斤牛肉
加了一个鸡腿
加了一个荷包蛋
的面条
************分割线**************
加了一个荷包蛋
的面条
总结
优缺点分析
优点:
- 装饰类和被装饰类可以独立发展,不会相互耦合。
- 装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。
缺点:
- 多层装饰比较复杂。
使用场合
- 如果你希望在无需修改代码的情况下即可使用对象,且希望在运行时为对象新增额外的行为,可以使用装饰模式。
- 如果用继承来扩展对象行为的方案难以实现或者根本不可行,你可以使用该模式。
热门推荐
保鲜冰箱多少度,确保食材新鲜的关键温度
MT管理器:误删文件也能救回来?
关注慢支患者心理健康:从专业干预到家庭照护
秋冬防病指南:慢性支气管炎患者的日常呼吸锻炼法
慢性支气管炎患者的科学饮食指南
用胶带“撕”出超薄金刚石膜
去除不干胶的技巧有哪些?如何选择合适的去除剂和方法?
侧睡压胸痛的原因是什么?
汽车尾气中的碳氢化合物:从危害到治理
2025央视春晚重庆分会场:立体舞台展现山城魅力,高校学子演绎青春风采
冬季自驾游如何防流感?这份实用指南请收好!
冬虫夏草当归炖牛肉:一道养生佳肴的制作与功效
昆明滇池寒潮来袭!这份冬日出行攻略请收好
《兰陵王》:一段跨越权力与命运的传奇爱情
冯绍峰版兰陵王:高长恭的情感纠葛
打卡兴坪古镇:拍出最美桂林照
桂林:万年智慧圣地,山水甲天下
COP16点赞:桂林山水生态保护
国庆打卡:徐州博物馆&狮子山楚王墓,感受汉代文明魅力
冬日徐州:云龙湖畔赏美景,方特乐园享欢乐
春节长途自驾旅游,这些要点需牢记,实用性强
双十一囤货指南:如何挑选优质干竹笋?
抵押车过户那些坑,你踩过几个?
湖南省加油站应急处理指南:如何应对“走单”和“跑冒油”
岳阳市云港路加氢站投运,助推中部地区氢能产业发展
情绪智力(情商):定义、重要性及提升方法
广州出发!神农架自驾游全攻略
神农架必打卡:华中第一峰与高山湿地的绝美邂逅
尚水美食街:桂林必打卡特色美食地图
灵渠与桂林米粉:两千年的历史渊源