装饰者模式-Decorator

场景描述:

煎饼果子,最普通是摊个煎饼,加个鸡蛋,加个薄脆等等

定义煎饼果子抽象基础类:

package com.decorator;

public abstract class ChinesePancake
{
    String description = "煎饼果子";
    
    public String getDescription(){
       return description; 
    }
    
    public abstract double cost();
}

定义一个装饰者类:

package com.decorator;

public abstract class ChinesePancakeDecorator extends ChinesePancake
{
    public abstract String getDescription();
}

定义一个普通的煎饼果子

package com.decorator;

public class CommonChinesePancake extends ChinesePancake
{

    public CommonChinesePancake(){
        description = "这是一个普通的煎饼果子";
    }

    public double cost()
    {
        return 5.00;
    }    
}

加个鸡蛋

package com.decorator;

public class EggDecorator extends ChinesePancakeDecorator
{
    ChinesePancake chinesePancake;
    
    public EggDecorator(ChinesePancake chinesePancake)
    {
        this.chinesePancake=chinesePancake;
    }
    
    public String getDescription()
    {
        return chinesePancake.getDescription()+ ",加个鸡蛋";
    }
    
    public double cost()
    {
        return 2.00 + chinesePancake.cost();
    }
}

加个薄脆

package com.decorator;

public class BaocuiDecorator extends ChinesePancakeDecorator
{
    ChinesePancake chinesePancake;

    public BaocuiDecorator(ChinesePancake chinesePancake)
    {
        this.chinesePancake=chinesePancake;
    }

    public String getDescription()
    {
        return chinesePancake.getDescription()+ ",加个薄脆";
    }

    public double cost()
    {
        return 1.00 + chinesePancake.cost();
    }
}

开始要摊煎饼果子了:

package com.decorator;

public class ChinesePancakeConsumer
{
    public static void main(String args[])
    {
        System.out.println("来个煎饼");
        ChinesePancake chinesePancake=new CommonChinesePancake();
        System.out.println(chinesePancake.getDescription()+":"+chinesePancake.cost()+"\n");
        
        System.out.println("来个煎饼加一个鸡蛋");
        ChinesePancake chinesePancake1=new CommonChinesePancake();
        chinesePancake1=new EggDecorator(chinesePancake1);
        System.out.println(chinesePancake1.getDescription()+":"+chinesePancake1.cost()+"\n");
        
        System.out.println("来个煎饼加一个鸡蛋再加一个薄脆");
        ChinesePancake chinesePancake2=new CommonChinesePancake();
        chinesePancake2=new EggDecorator(chinesePancake2);
        chinesePancake2=new BaocuiDecorator(chinesePancake2);
        System.out.println(chinesePancake2.getDescription()+":"+chinesePancake2.cost()+"\n");
    }
}

装饰者模式的应用场景:

1、  想透明并且动态地给对象增加新的职责的时候。

2、  给对象增加的职责,在未来存在增加或减少可能。

3、  用继承扩展功能不太现实的情况下,应该考虑用组合的方式。

装饰者模式的优点:

1、  通过组合而非继承的方式,实现了动态扩展对象的功能的能力。

2、  有效避免了使用继承的方式扩展对象功能而带来的灵活性差,子类无限制扩张的问题。

3、  充分利用了继承和组合的长处和短处,在灵活性和扩展性之间找到完美的平衡点。

4、  装饰者和被装饰者之间虽然都是同一类型,但是它们彼此是完全独立并可以各自独立任意改变的。

5、  遵守大部分GRASP原则和常用设计原则,高内聚、低偶合。

装饰者模式的缺点:

1、  装饰链不能过长,否则会影响效率。

2、  因为所有对象都是Component,所以如果Component内部结构发生改变,则不可避免地影响所有子类(装饰者和被装饰者),也就是说,通过继承建立的关系总是脆弱地,如果基类改变,势必影响对象的内部,而通过组合(Decoator HAS A Component)建立的关系只会影响被装饰对象的外部特征。

3、只在必要的时候使用装饰者模式,否则会提高程序的复杂性,增加系统维护难度。

你可能感兴趣的:(设计模式,Decorator,装饰者模式)