您的位置:首页 > 其它

设计模式之装饰者模式

2016-05-13 20:12 225 查看

罪恶的成绩单

故事从四年级的小明期末考试完后,拿着成绩单回家找老爸签字说起,我们小明的成绩是这样的:语文:12分 数学22分。小明路上这个忐忑啊,这点成绩家长能签字吗,不打死我就挺好的了。小明猜的没错,他爸的确会打他!看类图如下:



代码如下:

抽象成绩单

public abstract class SchoolReport {
//成绩单主要展示的就是你的成绩情况
public abstract void report();
//成绩单要家长签字,这个是最要命的
public abstract void sign();
}


四年级成绩单

public class FouthGradeSchoolReport extends SchoolReport {
//我的成绩单
public void report() {
//成绩单的格式是这个样子的
System.out.println("尊敬的XXX家长:");
System.out.println("    ......");

System.out.println(" 语文 12  数学22 ");
System.out.println("    .......");
System.out.println("    家长签名:   ");
}
//家长签名
public void sign(String name) {
System.out.println("家长签名为:"+name);
}
}


老爸查看成绩单

public class Father {
public static void main(String[] args) {
//把成绩单拿过来
SchoolReport sr = new FouthGradeSchoolReport();
//看成绩单
sr.report();
//签名?考这么点成绩,没打你就挺好的了,还想签名!
}
}


运行结果如下:

尊敬的XXX家长:
......

语文 62 数学65 体育 98 自然 63
.......

家长签名:


其实我们小明考的挺好,只是没有修饰

其实小明考的非常好,这次考试,语文最高分13分 数学最高分22分, 小明班级排名第一!所以我们小明死脑筋,不会装饰一下成绩单,下面我们来装饰一下,类图如下:



修饰的抽象类

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);
}
}


看到没,装饰类还是把动作的执行委托给需要装饰的对象,Decorator抽象类的目的很简单,就是要让子类来封装SchoolReport的子类,怎么封装?重写report方法!先看HighScoreDecorator实现类。

最高成绩修饰

public class HighScoreDecorator extends Decorator {
//构造函数
public HighScoreDecorator(SchoolReport sr){
super(sr);
}
//我要汇报最高成绩
private void reportHighScore(){
System.out.println("这次考试语文最高是75,数学是78,自然是80");
}
//我要在老爸看成绩单前告诉他最高成绩,否则等他一看,就抡起扫帚揍我,我哪里还有机会说啊
@Override
public void report(){
this.reportHighScore();
super.report();
}
}


重写了report方法,先调用具体装饰类的装饰方法reportHighScore,然后再调用具体构件的方法.

我们再来看怎么汇报学校排序情况SortDecorator代码

排名情况修饰

public class SortDecorator extends Decorator {
//构造函数
public SortDecorator(SchoolReport sr){
super(sr);
}
//告诉老爸学校的排名情况
private void reportSort(){
System.out.println("我是排名第38名...");
}
//老爸看完成绩单后再告诉他,加强作用
@Override
public void report(){
super.report();
this.reportSort();
}
}


我准备好了这两个强力的修饰工具,然后就“毫不畏惧”地把成绩单交给老爸,看看老爸怎么看成绩单的.

老爸查看修饰后的成绩单

public class Father {
public static void main(String[] args) {
//把成绩单拿过来
SchoolReport sr;
//原装的成绩单
sr = new FouthGradeSchoolReport();
//加了最高分说明的成绩单
sr = new HighScoreDecorator(sr);
//又加了成绩排名的说明
sr = new SortDecorator(sr);
//看成绩单
sr.report();
//然后老爸一看,很开心,就签名了
sr.sign("老三");  //我叫小三,老爸当然叫老三
}
}


老爸一看成绩单,听我这么一说,非常开心,赶紧签名。

想想看,如果我还要增加其他的修饰条件,是不是就非常容易了,只要实现Decorator类就可以了!这就是装饰模式。

装饰模式的优点和缺点

优点

● 装饰类和被装饰类可以独立发展,而不会相互耦合。换句话说,Component类无须知道Decorator类,Decorator类是从外部来扩展Component类的功能,而Decorator也不用知道具体的构件。

● 装饰模式是继承关系的一个替代方案。我们看装饰类Decorator,不管装饰多少层,返回的对象还是Component,实现的还是is-a的关系。

● 装饰模式可以动态地扩展一个实现类的功能,这不需要多说,装饰模式的定义就是如此。

缺点

对于装饰模式记住一点就足够了:多层的装饰是比较复杂的。为什么会复杂呢?你想想看,就像剥洋葱一样,你剥到了最后才发现是最里层的装饰出现了问题,想象一下工作量 吧,因此,尽量减少装饰类的数量,以便降低系统的复杂度。

结尾

好吧就讲到这里吧,点击下载代码
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: