前言:好像挺久没写过博客了,大概是变懒了没有开始那会儿的动力了,但是,学习以及记录的习惯还是不能丢的。OK,本文主要介绍java装饰者模式
。
一 什么是装饰者模式
就定义而言:装饰者模式指的是 -> 在不改变源代码的情况下,动态地给一个对象添加一些额外的职责。通过创建一个包装对象,也就是装饰者来包裹被装饰的对象。就增加功能来说,装饰者模式比生成子类(继承)更加灵活。
装饰者模式的作用
,简单的说就是,扩展原来有类的功能
。怎么样,是不是马上就想到了代理模式?
其实两者还是有区别的,装饰者模式重点在于灵活的扩展原有类的功能,而代理模式重点在于控制对对象的访问。具体就不多说了,有兴趣的朋友可以自行了解。
二 装饰者模式的组成
-
抽象组件Component
其实就是
被装饰者的基类
,一个接口,主要用来规范被装饰对象。 -
具体组件ConcreteComponent
其实就是
具体的被装饰者
,实现被装饰者的基类,也就是抽象组件。 -
装饰者抽象类Decorator
其实就是
装饰者的基类
,一个抽象类。用于规范以及组合具体的装饰者,进而实现灵活的对被装饰者进行装饰。Decorator必须持有抽象组件的对象实例引用
。 -
具体装饰者ConcreteDecorator
具体的装饰者,继承抽象的装饰者,具体为被装饰者增加什么功能就在这里得到体现。
三 装饰者模式具体实现
由于本人比较喜欢锻炼,没事的时候经常会去健身房活动活动筋骨(哈哈,预防猝死,从我做起)。所以,这里我就以健身房办卡为例,有的健身房单纯办一张年卡的话,就只能享受器械以及跑步机的使用权。对于其他的舞蹈,瑜伽,游泳等等之类的,则需要重新办理相应的业务。
所以,健身卡就会有很多种组合了。例如:1.年卡 2.年卡+游泳 3.年卡+舞蹈 4.年卡+瑜伽+舞蹈…
如果采用继承的方式实现健身卡,那么会有很多个类,很容易造成类爆炸,相比继承,装饰者模式在一定程度上可以大大减少类爆炸的问题。
OK,说了这么多是为了帮助大家更好的理解。接下来,直接上代码:
1.抽象组件(抽象的被装饰者)
/**
* 抽象的组件(抽象的被装饰者)
* <p>
* 这里以健身卡为例 健身卡有价格以及描述
*/
public interface GymCard {
//价格
public BigDecimal price();
//描述
public String desc();
}
2.具体组件(具体的被装饰者)
/**
* 具体组件(具体的被装饰者)
* 这是一张最原始的健身卡,只能使用跑步机以及器械
* 需要实现抽象组件,并实现规定的相应方法
*/
public class BasicGymCard implements GymCard {
@Override
public BigDecimal price() {
return BigDecimal.valueOf(1500L);
}
@Override
public String desc() {
return "健身年卡";
}
}
3.装饰者抽象类Decorator
/**
* 装饰者组件(装饰者抽象类)
* 1:需要实现抽象组件
* 2:需要持有抽象组件的对象实例引用
*/
public abstract class Decorator implements GymCard {
//持有抽象组件的对象实例引用 通过构造函数传入
private GymCard gymCard;
public Decorator(GymCard gymCard) {
this.gymCard = gymCard;
}
@Override
public BigDecimal price() {
return gymCard.price();
}
@Override
public String desc() {
return gymCard.desc();
}
}
4.具体装饰者ConcreteDecorator
/**
* 具体的装饰者之游泳业务
* 需要继承抽象的装饰者,并重写其方法,完成相应的功能增强
*/
public class Swim extends Decorator {
public Swim(GymCard gymCard) {
super(gymCard);
}
@Override
public BigDecimal price() {
return super.price().add(BigDecimal.valueOf(400L));
}
@Override
public String desc() {
return super.desc() + "+游泳";
}
}
此外,瑜伽以及舞蹈和游泳是一样的,都是健身卡具体的装饰者,代码是一样的,我就不重复贴出来了。
OK,接下来看测试类:
public class Test {
public static void main(String[] args) {
//基本的健身卡
GymCard gymCard = new BasicGymCard();
System.out.println(gymCard.desc());
System.out.println(gymCard.price());
//加瑜伽
GymCard yoGa = new Yoga(gymCard);
System.out.println(yoGa.desc());
System.out.println(yoGa.price());
//再加舞蹈
GymCard dance = new Dance(yoGa);
System.out.println(dance.desc());
System.out.println(dance.price());
//加游泳
GymCard swim = new Swim(gymCard);
System.out.println(swim.desc());
System.out.println(swim.price());
}
}
运行结果如下:
可以看到,我们可以随意组合装饰者,从而将健身卡的功能得到扩展。
最后,我们可以看看装饰者模式的UML类图
好了,关于装饰者模式的介绍就到这里了。
在JDK里面,IO流就是典型的装饰者模式的应用
,感兴趣的朋友可以去看看IO流的源代码或者UML类图~