设计模式之装饰者模式

来源:互联网 发布:安卓解压软件 编辑:程序博客网 时间:2024/06/03 20:06

罪恶的成绩单

故事从四年级的小明期末考试完后,拿着成绩单回家找老爸签字说起,我们小明的成绩是这样的:语文: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的关系。

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

缺点

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

结尾

好吧就讲到这里吧,点击下载代码

0 0