装饰模式
定义:
指的是在 “不必改变原类文件 ” 和 “不使用继承” 的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。
举例 ( 如何让家长在差的成绩单基础上看到感觉更好的成绩 ) :
正常的学校下发成绩单流程:
public abstract class SchoolReport {
public abstract void report();
public abstract void sign();
}
public class FourGradeSchoolReport extends SchoolReport {
@Override
public void report() {
System.out.println("语文 60 ,数学38, 英语26......");
}
@Override
public void sign() {
System.out.println("家长签名");
}
}
public class Father {
public void main() {
FourGradeSchoolReport schoolReport = new FourGradeSchoolReport();
schoolReport.report();
//签名,休想
//schoolReport.sign();
}
}
为了更好的修饰成绩单,在拿到成绩单之前做些手脚。先说出最高分,然后说自己的排名。
public class SugarFourGradeSchoolReport extends FourGradeSchoolReport {
//汇报最高分
public void reportHighScore() {
System.out.println("本次最高分66");
}
//汇报排名
public void reportSort() {
System.out.println("本次排名38");
}
@Override
public void report() {
reportHighScore();//优化一下,汇报最高分
super.report();
reportSort();//汇报排名
}
@Override
public void sign() {
super.sign();
}
}
public class Father {
public void main() {
FourGradeSchoolReport schoolReport = new FourGradeSchoolReport();
schoolReport.report();
//看到了report这么好,可以签名了。
schoolReport.sign();
}
}
引出问题:
如果我们还想继续修改,那么就要继续去继承,不仅继承超过了两层,而且类的数量会激增,维护起来也麻烦。还有基类的顺序可能会有改变。因此,要想办法引出第三种类来解决这种问题,具体新增内容的执行顺序放到子类进行。这时,装饰者模式就出现了。
public abstract class Decorator extends SchoolReport {
private SchoolReport sr;
public Decorator(SchoolReport sr) {
this.sr = sr;
}
@Override
public void report() {
this.sr.report();
}
@Override
public void sign() {
this.sr.sign();
}
}
/**
*装饰高分
*/
public class HighScoreDecorator extends Decorator {
public HighScoreDecorator(SchoolReport sr) {
super(sr);
}
public void reportHighSore() {
System.out.println("报告最高分");
}
@Override
public void report() {
reportHighSore();
super.report();
}
}
/**
* 装饰排名
*/
public class SortDecorator extends Decorator {
public SortDecorator(SchoolReport sr) {
super(sr);
}
public void reportSort() {
System.out.println("报告排名");
}
@Override
public void report() {
reportSort();
super.report();
}
}
public class Father{
public void main() {
SchoolReport sr;
sr = new FourGradeSchoolReport();
sr = new HighScoreDecorator(sr);//先报告最高分(两者顺序可变)
sr = new SortDecorator(sr);//先报告排名(两者顺序可变)
sr.report();
sr.sign();
}
}
总结:
使用了装饰者模式,不改变了原来的类文件,而且不使用集成,动态的、可选择性的装饰去完成了类的拓展。
最后引出类图: