设计模式-结构型模式之装饰器模式

86 阅读2分钟

结构型模式-装饰器模式

image.png

装饰器模式

装饰器模式:动态的给一个对象增加一些额外的功能,使用装饰器模式比生成子类更加灵活。

举个例子:用考试成绩单来说明,假设考试考了45分,学校要求必须拿给家长看,并签字拿回到学校。直接拿着成绩单给家长看,那可能是在考验父爱了。当然我们可以对成绩单做一下修饰,怎么修饰呢?比如说一下班级最高分?班级排名?当然也可能会换来更强的父爱。

那我们就以这个例子来写一下装饰器模式:

image.png

成绩单

成绩单可以直接用一个类表示,但是为了更好的扩展,这里我们加一个抽象类,用来表示成绩单,具体的实现就可以多样化,可以是三年级的成绩单、四年级的成绩单等。


成绩单抽象类:

public abstract class SchoolReport {  
    /**  
    * 成绩描述部分  
    */  
    abstract void report();  
    /**  
    * 签名  
    */  
    abstract void sign(String name);  
}

成绩单具体实现:

public class FouthGradeSchoolReport extends SchoolReport{  
    @Override  
    void report() {  
        System.out.println("四年级成绩单:XXX");  
        System.out.println("语文:43");  
        System.out.println("英语:32");  
        System.out.println("数学:38");  
    }  

    @Override  
    void sign(String name) {  
        System.out.println("家长签名为:"+name);  
    }  
}

装饰器

装饰器的抽象类:

public abstract class Decorator extends SchoolReport{  
    //被装饰的对象
    private SchoolReport schoolReport;  
    public Decorator(SchoolReport schoolReport) {  
        this.schoolReport = schoolReport;  
    }  
    @Override  
    void report() {  
        //装饰的时候,核心的步骤不变,还是要有报告单  
        schoolReport.report();  
    }  

    @Override  
    void sign(String name) {  
        //还是要签名  
        schoolReport.sign(name);  
    }  
}

最高分描述类:

public class HighScoreDecorator extends Decorator{  
    public HighScoreDecorator(SchoolReport schoolReport) {  
        super(schoolReport);  
    }  

    @Override  
    void report() {  
        System.out.println("班级最高分是语文:60,英语:59,数学:70");  
        super.report();  
    }  
}

排名描述类:

public class SortDecorator extends Decorator{  
  
    public SortDecorator(SchoolReport schoolReport) {  
        super(schoolReport);  
    }  

    @Override  
    void report() {  
        System.out.println("排名第28");  
        super.report();  
    }  
}

测试

public static void main(String[] args) {  
    SchoolReport schoolReport = new FouthGradeSchoolReport();  
    //这里就可以灵活的对被装饰对象选择是否装饰一层
    SortDecorator sortDecorator = new SortDecorator(schoolReport);  
    HighScoreDecorator highScoreDecorator = new HighScoreDecorator(sortDecorator);  
    highScoreDecorator.report();  
    highScoreDecorator.sign("张三");  
}

贴一个类图:

image.png


装饰器模式的优点:

  • 装饰类和被装饰类可以独立发展,在使用的时候可以灵活添加装饰

装饰器模式的缺点:

  • 增加了系统的复杂度,可能看到包装了很多层才看到具体的实现

使用场景:

  • 当需要动态的扩展某个类的功能时,可以增加也可以撤销