结构型模式-装饰器模式
装饰器模式
装饰器模式:动态的给一个对象增加一些额外的功能,使用装饰器模式比生成子类更加灵活。
举个例子:用考试成绩单来说明,假设考试考了45分,学校要求必须拿给家长看,并签字拿回到学校。直接拿着成绩单给家长看,那可能是在考验父爱了。当然我们可以对成绩单做一下修饰,怎么修饰呢?比如说一下班级最高分?班级排名?当然也可能会换来更强的父爱。
那我们就以这个例子来写一下装饰器模式:
成绩单
成绩单可以直接用一个类表示,但是为了更好的扩展,这里我们加一个抽象类,用来表示成绩单,具体的实现就可以多样化,可以是三年级的成绩单、四年级的成绩单等。
成绩单抽象类:
public abstract class SchoolReport {
/**
* 成绩描述部分
*/
abstract void report();
/**
* 签名
*/
abstract void sign(String name);
}
成绩单具体实现:
public class FouthGradeSchoolReport extends SchoolReport{
@Override
void report() {
System.out.println("四年级成绩单:XXX");
System.out.println("语文:43");
System.out.println("英语:32");
System.out.println("数学:38");
}
@Override
void sign(String name) {
System.out.println("家长签名为:"+name);
}
}
装饰器
装饰器的抽象类:
public abstract class Decorator extends SchoolReport{
//被装饰的对象
private SchoolReport schoolReport;
public Decorator(SchoolReport schoolReport) {
this.schoolReport = schoolReport;
}
@Override
void report() {
//装饰的时候,核心的步骤不变,还是要有报告单
schoolReport.report();
}
@Override
void sign(String name) {
//还是要签名
schoolReport.sign(name);
}
}
最高分描述类:
public class HighScoreDecorator extends Decorator{
public HighScoreDecorator(SchoolReport schoolReport) {
super(schoolReport);
}
@Override
void report() {
System.out.println("班级最高分是语文:60,英语:59,数学:70");
super.report();
}
}
排名描述类:
public class SortDecorator extends Decorator{
public SortDecorator(SchoolReport schoolReport) {
super(schoolReport);
}
@Override
void report() {
System.out.println("排名第28");
super.report();
}
}
测试
public static void main(String[] args) {
SchoolReport schoolReport = new FouthGradeSchoolReport();
//这里就可以灵活的对被装饰对象选择是否装饰一层
SortDecorator sortDecorator = new SortDecorator(schoolReport);
HighScoreDecorator highScoreDecorator = new HighScoreDecorator(sortDecorator);
highScoreDecorator.report();
highScoreDecorator.sign("张三");
}
贴一个类图:
装饰器模式的优点:
- 装饰类和被装饰类可以独立发展,在使用的时候可以灵活添加装饰
装饰器模式的缺点:
- 增加了系统的复杂度,可能看到包装了很多层才看到具体的实现
使用场景:
- 当需要动态的扩展某个类的功能时,可以增加也可以撤销