很久没有写博客了,最近也有很多事情要处理,也在努力的备考软件考试,正好模拟题中有一道关于装饰器模式的题,觉得还不错,所以特地写一篇文章希望能分享给小伙伴们。
装饰器模式的作用:允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。
接下来继续举一个简单的例子:
曾经的我每天打扫卫生只要扫扫地就好了,但是最近养了一只小猫咪,家里的卫生就得更加注意了,不得不每天扫地,拖地,喂猫,铲屎,真的好忙啊!但是为了可爱的小猫咪,我干了!
曾经:
现在:
有小伙伴们好奇为什么扫地不是跟其他家务在一列中呢?因为扫地是最主要的家务,不管有没有小猫咪都会扫地,我希望在不改变我扫地的原逻辑下,新增其他家务,这时候就可以使用装饰器模式。
代码逻辑如下:
主逻辑扫地类:
/**
* @description:扫地
* @author: Me
* @createDate: 2023/5/1 23:15
* @version: 1.0
*/
public class SaoDi {
public void doWork() {
System.out.println("扫个地");
}
}
装饰器控制类:
/**
* @description:装饰器开关,用于控制所有装饰器类
* @author: Me
* @createDate: 2023/5/1 23:15
* @version: 1.0
*/
public class Decorator extends SaoDi{
private SaoDi work;
// 构造器根据入参的类型,确定调用的方法,实际采用了多态的思想
public Decorator(SaoDi work) {
this.work = work;
}
public void doWork() {
if (work != null) {
// 根据传入家务的类型去调用做家务的方法
work.doWork();
}
}
}
三种不同的装饰器家务类:
/**
* @description:拖地
* @author: Me
* @createDate: 2023/5/1 23:19
* @version: 1.0
*/
public class TuoDi extends Decorator{
public TuoDi(SaoDi work) {
super(work);
}
// 做家务的方法
public void doWork() {
// 调用构造器中参数对象的做家务方法
super.doWork();
System.out.println("拖个地");
}
}
/**
* @description:喂猫
* @author: Me
* @createDate: 2023/5/1 23:21
* @version: 1.0
*/
public class WeiMao extends Decorator{
public WeiMao(SaoDi work) {
super(work);
}
// 做家务的方法
public void doWork() {
// 调用构造器中参数对象的做家务方法
super.doWork();
System.out.println("喂个猫");
}
}
/**
* @description:铲屎
* @author: Me
* @createDate: 2023/5/1 23:21
* @version: 1.0
*/
public class ChanShi extends Decorator{
public ChanShi(SaoDi work) {
super(work);
}
// 做家务的方法
public void doWork() {
// 调用构造器中参数对象的做家务方法
super.doWork();
System.out.println("铲个屎");
}
}
开始选择做哪些家务:
/**
* @description:调用类
* @author: Me
* @createDate: 2023/5/1 23:22
* @version: 1.0
*/
public class Test {
public static void main(String[] args) {
// 采用多重对象嵌套的逻辑来在扫地操作前后增加其他操作
// 如果doWork方法中,super.doWork在自己的方法逻辑前,则先执行创建对象时的参数对象方法
// 如果super.doWork方法在自己的方法逻辑之后,则先执行本对象方法,在寻找参数对象的方法
SaoDi work = new TuoDi(new WeiMao(new SaoDi()));
work.doWork();
}
}
如上图调用逻辑,执行结果如下:
这种模式的优点在于:
1.装饰类和被装饰类可以独立发展,不会相互耦合。
2.各个装饰类的职责清晰明了,便于动态扩展,动态撤销。
缺点:
1.多层装饰比较复杂,装饰器如果需要按自定义顺序执行时比较困难,上述例子中我们可以发现,类创建过后被装饰类SaoDi与其他装饰类的执行顺序就已经被确定了,SaoDi只能在其他的装饰类之前执行,无法在装饰类之后执行,如果需要在装饰类之后执行SaoDi的方法,则只能修改装饰类,并且嵌套创建对象来定义执行顺序需要对于方法比较熟悉,不太容易上手。
其他的内容在菜鸟教程中有比较详细的过程我就不在此赘述了,这篇文章的意义就是希望能够通过自己的理解尽可能形象的解释一下设计模式,使得抽象的内容理解起来变得简单些。