设计模式之装饰者模式
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的关系。
● 装饰模式可以动态地扩展一个实现类的功能,这不需要多说,装饰模式的定义就是如此。
缺点
对于装饰模式记住一点就足够了:多层的装饰是比较复杂的。为什么会复杂呢?你想想看,就像剥洋葱一样,你剥到了最后才发现是最里层的装饰出现了问题,想象一下工作量 吧,因此,尽量减少装饰类的数量,以便降低系统的复杂度。结尾
好吧就讲到这里吧,点击下载代码相关文章推荐
- Android自定义URL使用Scheme方式唤起Activity或App
- MPU6050在ROS中应用
- HttpURLConnection网络获取天气预报信息
- 团队项目第三天
- 聊聊并发(四)——深入分析ConcurrentHashMap
- 75. Sort Colors
- 关于数列an=n^t(t为常数)前n项求和公式的讨论
- Android transformClassesWithDexForAdh5Debug 的解决方法
- 砝码称重问题二
- JZOJ 3547【清华集训2014】mex
- KMP算法详解
- HDU-4027-Can you answer these queries?(线段树)
- linux如何进行swap分页(2016.5.13)
- <教育漫谈> 读书笔记 一
- 团队项目第二天
- wdcp v3 Forbidden :You don't have permission to access /phpmyadmin on this server
- 母函数
- Java学习之反射机制学习总结--1
- java21对象的转型
- CentOS 修改 Tomcat 端口