个人公众号【爱做梦的锤子】,全网同id,个站 http://te-amo.site,欢迎关注,里面会分享更多有用知识,还有我的私密照片
文章中部分定义和解释性文字,都是引用百度百科,主要的代码及场景应用为本人原创
装饰模式指的是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。
场景:我在我的网站设计时,一个图片处理的需求,上传照片要加水印,同时如果照片过大还要进行缩放,为了满足特定位置的大小,还需要进行裁剪。对于上面需求我想到了使用装饰者模式来设计,这样方便以后拓展功能,同时也不会对现有功能造成影响
设计
构成
- 抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象。(ImgEdit)
- 具体构件(Concrete Component)角色:定义一个将要接收附加责任的类。(ReadImg)
- 装饰(Decorator)角色:持有一个构件(Component)对象的实例,并实现一个与抽象构件接口一致的接口。(ImgDecorator)
- 具体装饰(Concrete Decorator)角色:负责给构件对象添加上附加的责任。(ImgCut,ImgWatermark,ImgZoom)
实现
代码地址:https://github.com/telundusiji/designpattern
抽象构件
public abstract class ImgEdit {
public abstract void handle();
}
具体构件 读取图片
@Slf4j
public class ReadImg extends ImgEdit {
private String path;
public ReadImg(String path){
this.path = path;
}
public void handle() {
log.info("图片{}读取中...",path);
log.info("读取完成!");
}
}
抽象装饰者
public abstract class ImgDecorator extends ImgEdit{
private ImgEdit imgEdit;
public ImgDecorator(ImgEdit imgEdit) {
this.imgEdit = imgEdit;
}
public ImgEdit getImgEdit() {
return imgEdit;
}
}
具体装饰者 图片剪裁
@Slf4j
public class ImgCut extends ImgDecorator {
public ImgCut(ImgEdit imgEdit) {
super(imgEdit);
}
public void handle() {
getImgEdit().handle();
log.info("裁剪操作...");
log.info("裁剪操作完成");
}
}
具体装饰者 图片添加水印
@Slf4j
public class ImgWatermark extends ImgDecorator {
public ImgWatermark(ImgEdit imgEdit) {
super(imgEdit);
}
public void handle() {
getImgEdit().handle();
log.info("添加水印...");
log.info("添加水印完成");
}
}
具体装饰者 图片缩放
@Slf4j
public class ImgZoom extends ImgDecorator {
public ImgZoom(ImgEdit imgEdit) {
super(imgEdit);
}
public void handle() {
getImgEdit().handle();
log.info("缩放操作...");
log.info("缩放操作完成");
}
}
经典应用
JDK中的IO类
- InputStream 抽象构件
- FileInputStream 具体构件
- FilterInputStream 抽象装饰者(虽然不是一个抽象类)
- BufferedInputStream、DataInputStream、PushbackInputStream … 具体装饰者
其实你也可以自己继承FilterInputStream 设计自己的装饰者
优缺点
优点:
- Decorator模式与继承关系的目的都是要扩展对象的功能,但是Decorator可以提供比继承更多的灵活性。
- 通过使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合,可以避免类爆炸
缺点:
- 这种比继承更加灵活机动的特性,也增加了复杂性
- 装饰模式会导致设计中出现许多小类,如果过度使用,会使程序变得复杂。
个人公众号【爱做梦的锤子】,全网同id,个站 http://te-amo.site,欢迎关注,里面会分享更多有用知识,还有我的私密照片