装饰器设计模式(Decorator Pattern):也叫包装器设计模式(Wrapper Pattern),指在不改变原有对象的基础上,动态地给对象添加一些额外的功能。就增加功能来说,装饰器模式相比生成子类更为灵活。
装饰设计模式的核心就是功能的扩展(增强),装饰器模式提供了比继承更有弹性的替代方案;
装饰设计模式有如下角色:
【对学生进行装饰(增强)】
一个普通的Java学生只会JavaSE、Servlet、JSP等技术,通过W3C网站装饰后的学生掌握了Spring、MyBaits、SpringMVC等技术,通过菜鸟教程网站装饰后掌握了Spring、Hibernate、Struts2等技术;
UML类图如下:

package com.pattern.demo;
/**
* @author lscl
* @version 1.0
* @intro: 抽象学生(抽象构建)
*/
public abstract class Student {
protected abstract void knowledge();
}
package com.pattern.demo;
/**
* @author lscl
* @version 1.0
* @intro: 普通Java学生(具体构建)
*/
public class JavaStudent extends Student {
@Override
protected void knowledge() {
System.out.println("JavaSE");
System.out.println("Servlet");
System.out.println("JSP");
}
}
package com.pattern.demo;
/**
* @author lscl
* @version 1.0
* @intro: 抽象学生装饰器(抽象装饰器)
*/
public abstract class StudentDecorator extends Student {
protected Student student;
public StudentDecorator(Student student){
this.student=student;
}
}
package com.pattern.demo;
/**
* @author lscl
* @version 1.0
* @intro: 具体装饰器
*/
public class W3cSchoolStudentDecorator extends StudentDecorator {
public W3cSchoolStudentDecorator(Student student) {
super(student);
}
@Override
protected void knowledge() {
// 学生原有功能
student.knowledge();
System.out.println("MyBatis");
System.out.println("Spring");
System.out.println("SpringMVC");
}
}
package com.pattern.demo;
/**
* @author lscl
* @version 1.0
* @intro: 具体装饰器
*/
public class CaiNiaoStudentDecorator extends StudentDecorator {
public CaiNiaoStudentDecorator(Student student) {
super(student);
}
@Override
protected void knowledge() {
// 保留原有的功能
student.knowledge();
System.out.println("Spring");
System.out.println("Hibernate");
System.out.println("Struts2");
}
}
package com.pattern.demo;
/**
* @author lscl
* @version 1.0
* @intro:
*/
public class Demo01 {
public static void main(String[] args) {
// 没有装饰的Java学生
System.out.println("没有装饰的Java学生: ");
Student javaStudent=new JavaStudent();
javaStudent.knowledge();
System.out.println("-------------------");
// 经过W3c加强的学生
System.out.println("经过W3c加强的学生: ");
StudentDecorator w3cSchoolStudentDecorator=new W3cSchoolStudentDecorator(javaStudent);
w3cSchoolStudentDecorator.knowledge();
System.out.println("-------------------");
// 经过菜鸟教程加强的学生
System.out.println("经过菜鸟教程加强的学生: ");
StudentDecorator caiNiaoStudentDecorator=new CaiNiaoStudentDecorator(javaStudent);
caiNiaoStudentDecorator.knowledge();
System.out.println("-------------------");
System.out.println("经过W3c和菜鸟教程加强的学生: ");
new CaiNiaoStudentDecorator(new W3cSchoolStudentDecorator(new JavaStudent())).knowledge();
}
}
从代理模式和装饰器模式的实现代码上来看,两者几乎一模一样。但其实两者有着本质的不同;
使用装饰器设计模式强调的是自身功能的扩展。即什么事情都自己干,自己不会就去学习,装饰器本身也是一个抽象组件的子类,装饰器(Decorator)就是增强具体组件(ConcreteComponent)的功能上的封装;
代理设计模式强调的增强后的结果,即只在乎结果,不在乎过程,自己不干增强的事情,自己不会做就找其他人(代理对象)做;然后最终达到目标效果即可;