装饰者模式

原文地址:https://www.jianshu.com/p/2fe021a2a9df

为现有的类增加功能,是继承的一种替代方式
类图如下

 

装饰者模式

装饰者模式类图

假设一个场景
我们在学校要考试,然后要给家长签字,说分数之前你要先汇报一下班级最好成绩,然后说出你的分数之后,在说出你在班级的排名
1,建立一个抽象的报告接口

public interface SchoolReport {
    void report();
    void sign(String name);
}

2,实现这个成绩报告接口

public class FourthGradeSchoolReport implements SchoolReport{
    @Override
    public void report() {
        System.out.println("尊敬的家长");
        System.out.println("``````````");
        System.out.println("语文 62 数学 65 体育89 自然63");
        System.out.println("``````````");
        System.out.println("家长签名:");
    }

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

3,建立一个公共装饰类,具体的装饰要在具体装饰类中定义


    private SchoolReport sr;

    public Decorator(SchoolReport sr){
        this.sr = sr;
    }


    @Override
    public void report() {
        this.sr.report();
    }

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

5,创建具体的装饰,最高分装饰类

public class HighScoreDecorator extends Decorator{

    public HighScoreDecorator(SchoolReport sr) {
        super(sr);
    }

    private void reportHighScore(){
        System.out.println("这次考试最高分 语文 75 数学 78 体育93 自然80");
    }

    @Override
    public void report() {
        this.reportHighScore();
        super.report();
    }
}

6,学校排名装饰类

public class SortScoreDecorator extends Decorator{

    public SortScoreDecorator(SchoolReport sr) {
        super(sr);
    }

    private void reportSort(){
        System.out.println("我的排名第38名");
    }

    @Override
    public void report() {
        super.report();
        this.reportSort();
    }
}

7,实现调用

public class Main {
    public static void main(String[] args){
        SchoolReport sr = new FourthGradeSchoolReport();
        sr = new HighScoreDecorator(sr);
        sr = new SortScoreDecorator(sr);
        sr.report();
        sr.sign("张三");
    }
}

总结,如果说我们要实现更多的功能可以创建更多的装饰具体装饰类,装饰类和被装饰类可独立发展,互相不耦合
缺点是,多层装饰比较复杂