设计模式-结构型模式-装饰模式
栗子
以成绩单需要家长签字为要求。
成绩单类图
// 抽象成绩单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攻击
表单验证,将表单验证的内容,写成一个类,然后需要哪个验证的选项,直接将表单验证传入即可,达到装饰器的目的,同时也达到了插件式的验证。
总结
核心在于装饰二字,将要装饰的对象,通过构造函数传入,然后再赋值,达到装饰的目的,然后再次调用即可。