背景:四年级期末考成绩单打印出来,要家长签字。
一、 成绩单抽象类
package com.teng.pattern.abs;
/**
* 学校成绩单
* <br>创建日期:2016年7月9日
* <br><b>Copyright 2016 tengxiang All Rights Reserved</b>
* @author tengxiang
* @since 1.0
* @version 1.0
*/
public abstract class SchoolReport {
/**
* @since 1.0
* <br><b>作者: @author tengxiang</b>
* <br>创建时间:2016年7月9日 下午10:18:29
*/
public abstract void report();
/**
* @since 1.0
* @param name
* <br><b>作者: @author tengxiang</b>
* <br>创建时间:2016年7月9日 下午10:18:33
*/
public abstract void signup(String name);
}
二、 成绩单的实现
package com.teng.pattern.impl;
import com.teng.pattern.abs.SchoolReport;
/**
* 报告单实现类
* <br>创建日期:2016年7月9日
* <br><b>Copyright 2016 tengxiang All Rights Reserved</b>
* @author tengxiang
* @since 1.0
* @version 1.0
*/
public class FourthGradeSchoolReport extends SchoolReport {
@Override
public void report() {
System.out.println("语文 78,数学 67,英语 82");
}
@Override
public void signup(String name) {
System.out.println("家长签字: "+name);
}
}
三、装饰类,及其两个实现
package com.teng.pattern.abs;
/**
* 装饰抽象类
* <br>创建日期:2016年7月9日
* <br><b>Copyright 2016 tengxiang All Rights Reserved</b>
* @author tengxiang
* @since 1.0
* @version 1.0
*/
public abstract class Decorator extends SchoolReport {
private SchoolReport sr;
/**
* 构造函数
* @param sr sr
*/
public Decorator(SchoolReport sr){
this.sr = sr;
}
@Override
public void report() {
this.sr.report();
}
@Override
public void signup(String name) {
this.sr.signup(name);
}
}
通过增加一个子类重写report方法。
package com.teng.pattern.impl;
import com.teng.pattern.abs.Decorator;
import com.teng.pattern.abs.SchoolReport;
/**
* 装饰实现类,最高分
* <br>创建日期:2016年7月9日
* <br><b>Copyright 2016 tengxiang All Rights Reserved</b>
* @author tengxiang
* @since 1.0
* @version 1.0
*/
public class HighScoreDecorator extends Decorator {
private void highScore(){
System.out.println("语文最高分80,数学最高分82,英语最高分89");
}
/**
* 构造器
* @param sr sr
*/
public HighScoreDecorator(SchoolReport sr) {
super(sr);
}
@Override
public void report() {
this.highScore();
super.report();
}
}
package com.teng.pattern.impl;
import com.teng.pattern.abs.Decorator;
import com.teng.pattern.abs.SchoolReport;
/**
* 装饰实现类,排名
* <br>创建日期:2016年7月9日
* <br><b>Copyright 2016 tengxiang All Rights Reserved</b>
* @author tengxiang
* @since 1.0
* @version 1.0
*/
public class SortSchoolReport extends Decorator {
/**
* 构造器
* @param sr sr
*/
public SortSchoolReport(SchoolReport sr) {
super(sr);
}
private void sort(){
System.out.println("全班排名第25名。。。");
}
@Override
public void report() {
super.report();
this.sort();
}
}
爸爸签字:
package com.teng.pattern.impl;
import com.teng.pattern.abs.SchoolReport;
/**
* 爸爸签字
* <br>创建日期:2016年7月9日
* <br><b>Copyright 2016 tengxiang All Rights Reserved</b>
* @author tengxiang
* @since 1.0
* @version 1.0
*/
public class Father {
/**
* @since 1.0
* @param args
* <br><b>作者: @author tengxiang</b>
* <br>创建时间:2016年7月9日 下午11:06:35
*/
public static void main(String[] args) {
//原装成绩单
SchoolReport sr = new FourthGradeSchoolReport();
//加了最高分
sr = new HighScoreDecorator(sr);
//加了排名
sr = new SortSchoolReport(sr);
//查看成绩单
sr.report();
//签字
sr.signup("老三");
}
}
Component是一个接口或者是抽象类,就是定义我们最核心的对象,也就是最原始的对象,比如上面的成绩单,记住在设计模式中,必然有一个被提取出来最核心、最原始、最基本的接口或抽象类,就是Component。
ConcreteComponent这个事最核心、最原始、最基本的接口或抽象类的实现,你要装饰的就是这个东东。
Decorator一般是一个抽象类,做什么用呢?实现接口或者抽象方法,它里面可不一定有抽象的方法呀,在它的属性类必然有一个private变量指向Component。
ConcreteDecoratorA和ConcreteDecoratorB是两个具体的装饰类,你要把你最核心的、最原始的、最基本的东西装饰成啥东西,上面的例子就是把一个比较平庸的成绩单装饰成家长认可的成绩单。
装饰模式是对继承的有力补充,你要知道继承可不是万能的。
装饰模式可以替代继承,解决我们类膨胀的问题,你要知道继承是静态的给类增加功能,而装饰模式则是动态的给增加功能。
装饰模式还有一个非常好的优点,扩展性非常好。
创建一个新的类,这个对原有程序没有变更,通过扩充很好的完成了这次变更。