设计模式 - 装饰者模式

定义:装饰者模式动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。

对象:

    抽象组件:定义一个抽象类或接口,来规范准备附加功能的类;

    具体组件:将要被附加功能的类,实现抽象构件角色抽象类或接口;

    抽象装饰者:持有对具体构件角色的引用并定义与抽象构件角色一致的接口;

      具体装饰:实现抽象装饰者角色,负责对具体构件添加额外功能。

 

代码示例:

场景为一个肉夹馍为5元,动态的为它添加佐料来改变价格。

抽象组件:

package com.decorator;

public interface CalculatePrice {
    
    float calcute();

}
View Code

具体组件:

package com.decorator;

public class RouJiaMePrice implements CalculatePrice {

    @Override
    public float calcute() {
        return 5.0F;
    }

}
View Code

抽象装饰者:

package com.decorator;

public abstract class Decorator implements CalculatePrice {

}
View Code

具体装饰:

package com.decorator;

public class LiJi extends Decorator {

    private CalculatePrice calculatePrice;
    
    public LiJi(CalculatePrice calculatePrice) {
        super();
        this.calculatePrice = calculatePrice;
    }

    @Override
    public float calcute() {
        return calculatePrice.calcute() + liJiPrice();
    }
    
    private float liJiPrice(){
        return 1.0F;
    }

}
View Code
package com.decorator;

public class PeiGen extends Decorator {
    
    private CalculatePrice calculatePrice;

    public PeiGen(CalculatePrice calculatePrice) {
        super();
        this.calculatePrice = calculatePrice;
    }

    @Override
    public float calcute() {
        return calculatePrice.calcute() + peiGenPrice();
    }
    
    private float peiGenPrice(){
        return 1.0F;
    }

}
View Code

测试代码:

package com.decorator;

public class TestDecorator {
    
    public static void main(String[] args) {
        CalculatePrice rouJiaMePrice = new RouJiaMePrice();
        System.out.println("原始价格:" + rouJiaMePrice.calcute() + "元");
        
        CalculatePrice liJi = new LiJi(rouJiaMePrice);
        System.out.println("原始价格 加里脊:" + liJi.calcute() + "元");
        
        CalculatePrice peiGen = new PeiGen(rouJiaMePrice);
        System.out.println("原始价格 加培根:" + peiGen.calcute() + "元");
        
        CalculatePrice price = new PeiGen(new LiJi(rouJiaMePrice));
        System.out.println("原始价格 加里脊和培根:" + price.calcute() + "元");
    }

}
View Code

总结:

1、装饰者和被装饰者有相同的超类型

2、装饰者保存了一个被装饰者的引用;

3、可以动态添加新功能,而不须修改现有的代码;

4、JDK库中的I/O中就使用了装饰者模式进行文件的读取;

 

posted @ 2017-05-30 17:37  吉良吉影的冒险  阅读(151)  评论(0编辑  收藏  举报