装饰模式

本文通过一个学生时代成绩单的小故事,引入并解释了装饰模式的概念及其实现方式。文章使用Java代码展示了如何通过装饰模式来动态地扩展成绩单的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  还依然清晰的记得以前上小学时,每次月考考试卷都要给家长签字,分数考得高时就不担心签名的问题,但是常在岸边走哪有不湿鞋,总有那么几次考不好,然后成绩波动太大,此时给家长签字时轻则一顿逼逼,重则一顿挨揍(当然不是狼妈虎爸一样,一天一顿打,孩子上北大)。有时为了避免这波暴击伤害,我们经常会把分数改一下(65就加一笔变成85)或者说找个理由(试卷太难,大家分数都不高等)。下面有程序猿的语言来描述这段经历。

抽象成绩单:

public abstract class GradeReport
{
        //向家长汇报
        public abstract void report();
        //家长签名
        public abstract void sign(String name);
}

具体成绩单:

public class MyReport extends  GradeReport
{

    @Override
    public void report()
    {
        // TODO Auto-generated method stub
        System.out.println("xxxx的家长,xxxx同学的总成绩180分(试卷总分300分)");
    }

    @Override
    public void sign(String name)
    {
        // TODO Auto-generated method stub
        System.out.println("家长姓名:"+name);
    }

}

抽象装饰类(在怎么装饰他还是一张成绩单)

public abstract class Decorate extends GradeReport
{
    GradeReport gradeReport;
    public Decorate(GradeReport gradeReport)
    {
        this.gradeReport = gradeReport;
    }
    @Override
    public void report()
    {
        this.gradeReport.report();
    }

    @Override
    public void sign(String name)
    {
        this.gradeReport.sign(name);
    }
}

具体装饰类:

public class MyDecorate extends Decorate
{

    public MyDecorate(GradeReport gradeReport)
    {
        super(gradeReport);
        // TODO Auto-generated constructor stub
    }
    public void highReport()
    {
        System.out.println("由于本次试卷难度比较大,180分已经是不错了");
    }
    @Override
    public void report()
    {
        // TODO Auto-generated method stub

        super.report();
        this.highReport();
    }
}

场景类:

public class Client
{
        public static void main(String[] args)
        {
                GradeReport report = new MyReport();
                Decorate decorate = new MyDecorate(report);
                decorate.report();
                decorate.sign("xx的家长");
        }
}

运行结果:

xxxx的家长,xxxx同学的总成绩180分(试卷总分300分)
由于本次试卷难度比较大,180分已经是不错了
家长姓名:xx的家长

  修饰之前只打印出总成绩为180分,想一下小学生300分只考了180很烂了,签名之前绝对少不了一顿逼逼,通过装饰家长很乐意就签上了大名,如果我们需要修饰一下总分排名为班级前列,那么我们只需要重新自定义一个Decorate类就可以实现,这就是装饰模式。

装饰模式定义
  装饰模式:Attach additional responsibilties to an object dynamically keeping the same interface. Decorate provider a flexible alternative to subclassing for extending functionality.(动态的给一个对象附加一些额外的职责。就增加新功能来说,装饰模式比生成子类更灵活)。

装饰模式的角色
  抽象构件Component:通常是一个接口或者抽象类,定义我们的核心对象,也是最原始的对象,比如我们上面的原始成绩单。
  具体构建ConcreteComponent:最原始、最基本的抽象类或接口的实现,我们需要装饰的就是他。比如例子中的MyGradeReport。
  抽象装饰角色:属性中存在一个Component的引用。
具体装饰角色:就是我们需要给ConcreteComponent装饰的东西都在这,上面的例子就是把查成绩单装饰成家长能接受的成绩单。

装饰模式的优点:
  1.装饰类和被装饰类独立发展不耦合,原始成绩单不需要知道装饰类,装饰类是从外部进行扩充。
  2.装饰模式是继承的一种替代方案,不管装饰了多少次,他最终还是一张成绩单。
  3.装饰模式可以动态的扩展实现类的功能。
装饰模式的缺点:
  装饰层数多了,如果最里层的装饰类出了问题,那么追踪问题就会非常复杂,需要像剥洋葱一样一层层往里排查,增加了系统的复杂度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值