设计模式-结构型模式-装饰模式
栗子
以成绩单需要家长签字为要求。
成绩单类图
// 抽象成绩单
public abstract class SchoolReport{
// 成绩单你的成绩情况
public abstract void report();
// 成绩单要求家长签字
public abstract void sign();
}
下面书写四年级成绩单
public class FouthGradeSchoolReport extends SchoolReport{
// 自己的成绩单
public void report(){
}
// 家长签名
public void sign(String name){
}
}
使用装饰器模式
使用装饰器模式,对成绩单进行装饰。
直接增加一个子类,重写report方法。
// 在成绩单下增加一个子类
public class SugarFouthGradeSchoolReport extends FouthGradeSchoolReport{
// 对成绩进行美化
private void reportHighScore(){
}
// 看完成绩单,再汇报排名
private void reportSort(){
}
// 对父类重写,即report原先的成绩单进行重写
public void report(){
this.reportHighScore(); // 最高成绩
// 显示成绩单
super.report();
// 再告诉排名
this.reportSort();
}
}
最后场景类
public class Father{
public static void main(String[] args){
// 生成美化后的成绩单
SchoolReport sr = new SugarFouthGradeSchoolReport();
// 看成绩单
sr.report();
// 签名
sr.sign("");
}
}
继续改进
如果要装饰的太多,不可能无限的增加子类。
代码如下
public abstract class Decorator extends SchoolReport{
// 要知道那个成绩单
private SchoolReport sr;
// 构造函数,传递成绩单
public Decorator(SchoolReport sr){
this.sr = sr;
}
// 装饰完成以后,需要有看到的需求
public void report(){
this.sr.report();
}
// 装饰完成后进行签名
public void sign(String name){
this.sr.sign(name);
}
}
核心在于通过构造函数,将要装饰的对象传入。再重写方法。
public class HighScoreDecorator extends Decorator {
// 构造函数
public HighScoreDecorator(SchoolReport sr){
super(sr);
}
// 对成绩修改
private void reportHighScore(){
}
// 重写汇报方法,对进行进行汇报
public void report(){
this.reportHighScore();
this.report();
}
}
然后紧接着,对排名进行修饰
public class SortDecorator extends Decorator{
// 构造函数
public SortDecorator(SchoolReport sr){
super(sr);
}
// 对排名装饰
private void reportSort(){
}
// 输出成绩
public void report(){
super.report();
this.reportSort();
}
}
最后书写场景类
public class Father{
public static void main(String[] args){
// 定义成绩单
SchooReport sr;
// 获取原装成绩单
sr = new FouthGradeSchoolReport();
// 对成绩单进行装饰
sr = new HighScoreDecorator(sr);
sr = new SortDecorator(sr);
// 最后,看成绩单
sr.report();
// 签名
sr.sign("");
}
}
应用
登录页面数据上报,使用装饰器,将登录层页面,上传到上报类中,进行装饰上统计代码,然后将统计数据上报。
动态改变函数参数,原先有一个正常的函数,通过装饰器,将正常的函数传入,装饰模式
应用ajax加token防止csrf攻击
表单验证,将表单验证的内容,写成一个类,然后需要哪个验证的选项,直接将表单验证传入即可,达到装饰器的目的,同时也达到了插件式的验证。
总结
核心在于装饰二字,将要装饰的对象,通过构造函数传入,然后再赋值,达到装饰的目的,然后再次调用即可。