装饰器模式
定义
装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。
解释
举个例子,小倩颜值一般,很喜欢拍照,但是拍出来的照片颜值只有60分,她非常想拍出来的照片颜值高一些,这时候有什么办法?
一种是整容,整完以后,人好看了,照片颜值自然就上去了,但是这种办法成本太高,还有风险,不推荐
还有一种方法呢,就是我们的P图大法,比如加个磨皮可以增加10点颜值,瘦脸可以增加15点颜值,滤镜可以增加10点颜值…这个成本就很低了,而且还可以按照自己的意愿进行叠加效果
装饰器模式就类似于我们的P图大法,在我们的现在代码结构不发生改变的情况下,可以增加新的功能(装饰)
把上面说的例子用代码来实现一下
Demo
GirlPicture.java
//先把女孩照片抽象出一个的抽象类,
public abstract class GirlPicture {
//获取照片信息
protected abstract String getMsg();
//获取照片颜值
protected abstract int getYanZhi();
}
YuanTu.java
//原图
public class YuanTu extends GirlPicture {
@Override
protected String getMsg() {
return "原图";
}
@Override
protected int getYanZhi() {
//原图颜值60
return 60;
}
}
PictureDecotator.java
//照片装饰器,可以理解为我们的PS软件的抽象
public abstract class PictureDecotator extends GirlPicture{
private GirlPicture girlPicture;
//进行P图肯定是要传入一张照片的
public PictureDecotator(GirlPicture girlPicture) {
this.girlPicture = girlPicture;
}
@Override
protected String getMsg() {
return this.girlPicture.getMsg();
}
@Override
protected int getYanZhi() {
return this.girlPicture.getYanZhi();
}
}
MoPiDecotator.java
//磨皮功能,具体的PS功能实现
public class MoPiDecotator extends PictureDecotator{
public MoPiDecotator(GirlPicture girlPicture) {
super(girlPicture);
}
@Override
protected String getMsg() {
//原信息基础上加上磨皮
return super.getMsg() + "加磨皮";
}
@Override
protected int getYanZhi() {
//原颜值+10
return super.getYanZhi() + 10;
}
}
ShouLianDecotator.java
//再来个瘦脸功能
public class ShouLianDecotator extends PictureDecotator{
public ShouLianDecotator(GirlPicture girlPicture) {
super(girlPicture);
}
@Override
protected String getMsg() {
return super.getMsg() + "加瘦脸";
}
@Override
protected int getYanZhi() {
return super.getYanZhi() + 15;
}
}
Test.java
public class Test {
public static void main(String[] args) {
//原图
GirlPicture girlPicture = new YuanTu();
System.out.println("该照片信息为:" + girlPicture.getMsg() + ", Girl的颜值为:" + girlPicture.getYanZhi());
//加一次磨皮,把原图传进去
girlPicture = new MoPiDecotator(girlPicture);
System.out.println("该照片信息为:" + girlPicture.getMsg() + ", Girl的颜值为:" + girlPicture.getYanZhi());
//加一次瘦脸,把之前的图传进去
girlPicture = new ShouLianDecotator(girlPicture);
System.out.println("该照片信息为:" + girlPicture.getMsg() + ", Girl的颜值为:" + girlPicture.getYanZhi());
//可以继续往下叠加
//...
}
}
类图
Component:最基本的统一接口,可以是接口或者抽象类,比如上面的GirlPicture
ConcreteComponent:需要被装饰的类,比如上面的YuanTu
Decorator:装饰器的统一接口,初始化时需要把被装饰的类传进去,比如上面的PictureDecotator
ConcreteDecoratorA和B:装饰器的具体实现类,对应上面的MoPiDecotator和ShouLianDecotator