简单的装饰者模式

装饰者模式主要用来扩展功能的,不会改变原来对象的功能,只做扩展

版本一:

简单的装饰者模式_第1张图片

 

简单的装饰者模式_第2张图片

 

代码如下:

 

public abstract class BeefNoodle {
    protected abstract String getMsg();
    protected abstract int getPrice();
}

 

 

public class BaseBeefNoodle extends BeefNoodle {

    protected String getMsg(){
        return "牛肉面";
    }

    public int getPrice(){
        return 5;
    }
}

 

public class EggDecorator extends BeefNoodle {

    private BeefNoodle beefNoodle;
    public EggDecorator(BeefNoodle beefNoodle) {
        this.beefNoodle = beefNoodle;
    }



    //增强的功能(基于真实对象上)
    protected String getMsg() {
        return beefNoodle.getMsg() + "+1个鸡蛋";
    }

    //增强的功能(基于真实对象上)
    protected int getPrice() {
        return beefNoodle.getPrice() + 1;
    }
}

 

private BeefNoodle beefNoodle;
public SausageDecorator(BeefNoodle beefNoodle) {
    this.beefNoodle = beefNoodle;
}


protected String getMsg() {
    return beefNoodle.getMsg() + "+1根香肠";
}


protected int getPrice() {
    return beefNoodle.getPrice() + 2;
}

 

测试代码:

public class MyTest {

    public static void main(String[] args) {

        BeefNoodle beefNoodle;
        //买一碗牛肉
        beefNoodle = new BaseBeefNoodle();
        //加一个鸡蛋
        beefNoodle = new EggDecorator(beefNoodle);
        //加根香肠
        beefNoodle = new SausageDecorator(beefNoodle);
        System.out.println(beefNoodle.getMsg()+"总价:"+beefNoodle.getPrice());
    }
}

 

效果如下:

简单的装饰者模式_第3张图片

简单的装饰者模式_第4张图片

简单的装饰者模式_第5张图片

 

版本二:

①根据策略模式获取对应的策略对象

②计算价格用具体的某一个装饰者对象去计算,因为会需要面的基本信息,所以作为构造参数传进来(代表这个对象是被增强的目标),此外各个装饰者对象还扩展了自己的功能,比如 混合了鸡蛋和香肠的类,方法就有三个参数(代表碗数量,鸡蛋数量,烤肠数量)

类图:

简单的装饰者模式_第6张图片

代码如下:

public abstract class BeefNoodle {
    protected abstract String getMsg(Integer amount);
    protected abstract int getPrice(Integer amount);
}

 

public class BaseBeefNoodle extends BeefNoodle {


    //amount 牛肉面数量
    protected String getMsg(Integer amount){
        return "牛肉面 * "+String.valueOf(amount);
    }

    //amount 牛肉面数量
    public int getPrice(Integer amount){
        return 5*amount;
    }
}

 

public class EggDecorator extends BeefNoodle {

    private BeefNoodle beefNoodle;

    public EggDecorator(BeefNoodle beefNoodle) {
        this.beefNoodle = beefNoodle;
    }

    protected String getMsg(Integer eggs) {
        return beefNoodle.getMsg(1) + "加"+String.valueOf(eggs)+"个鸡蛋";
    }

    protected int getPrice(Integer eggs) {
        return beefNoodle.getPrice(1) + 1*eggs;
    }


    protected String getMsg(Integer noodles,Integer eggs) {
        return beefNoodle.getMsg(noodles) + "加"+String.valueOf(eggs)+"个鸡蛋";
    }

    protected int getPrice(Integer noodles ,Integer eggs) {
        return beefNoodle.getPrice(noodles) + 1*eggs;
    }

}

 

public class SausageDecorator extends BeefNoodle {

    private BeefNoodle beefNoodle;


    public SausageDecorator(BeefNoodle beefNoodle) {
        this.beefNoodle = beefNoodle;
    }

    protected String getMsg(Integer sausages) {
        return beefNoodle.getMsg(1) + "加"+String.valueOf(sausages)+"根香肠";
    }


    protected int getPrice(Integer sausages) {
        return beefNoodle.getPrice(1) + 2*sausages;
    }


    protected String getMsg(Integer noodles ,Integer sausages) {
        return beefNoodle.getMsg(sausages) + "加"+String.valueOf(sausages)+"根香肠";
    }

    protected int getPrice(Integer noodles ,Integer sausages) {
        return beefNoodle.getPrice(noodles) + 1*sausages;
    }


}

 

public class EggsAndSausageDecorator extends BeefNoodle {

    private BeefNoodle beefNoodle;


    public EggsAndSausageDecorator(BeefNoodle beefNoodle) {
        this.beefNoodle = beefNoodle;
    }

    protected String getMsg(Integer sausages) {
        //return beefNoodle.getMsg(1) + "加"+String.valueOf(sausages)+"根香肠";
        return "";
    }


    protected int getPrice(Integer sausages) {
        //return beefNoodle.getPrice(1) + 2*sausages;
        return 0;
    }

    protected String getMsg(Integer noodles ,Integer eggs,Integer sausages) {
        return beefNoodle.getMsg(sausages) + "加"+String.valueOf(eggs)+"个鸡蛋"+"加"+String.valueOf(sausages)+"根香肠";
    }

    protected int getPrice(Integer noodles,Integer eggs,Integer sausages) {
        return beefNoodle.getPrice(noodles) +1*eggs +2*sausages;
    }

 

 

// 策略模式,获得不同的策略对象,具体的计算方式是在各个策略对象(装饰者对象)实现的
public class Strategy {

    public static final String ONLY_NOODLE = "Noodle";
    public static final String WITH_EGGS = "Eggs";
    public static final String WITH_SAUSAGES = "Sausages";
    public static final String WITH_EGGS_AND_SAUSAGES = "EggsAndSausages";


    private static Map noodleStrategy = new HashMap();
    static{
        BeefNoodle beefNoodle =  new BaseBeefNoodle();
        noodleStrategy.put(ONLY_NOODLE,beefNoodle);
        noodleStrategy.put(WITH_EGGS,new EggDecorator(beefNoodle));
        noodleStrategy.put(WITH_SAUSAGES,new SausageDecorator(beefNoodle));
        noodleStrategy.put(WITH_EGGS_AND_SAUSAGES,new EggsAndSausageDecorator(beefNoodle));
    }
    public static BeefNoodle get(String noodleKey){
        if(!noodleStrategy.containsKey(noodleKey)){
            return noodleStrategy.get(ONLY_NOODLE);
        }
        return noodleStrategy.get(noodleKey);
    }


}

测试类:
public class MyTest {

    public static void main(String[] args) {
       //选择不同的策略
       //一碗牛肉面
        BeefNoodle onlyBeefNoodle =   Strategy.get(Strategy.ONLY_NOODLE);
        System.out.println("只来一碗牛肉面"+onlyBeefNoodle.getMsg(1)+"价格为:"+ String.valueOf(onlyBeefNoodle.getPrice(1)));
        //两碗面
        System.out.println("只来两碗牛肉面"+onlyBeefNoodle.getMsg(2)+"价格为:"+ String.valueOf(onlyBeefNoodle.getPrice(2)));


        // 策略模式选择加 鸡蛋的 策略; 要用子类的方法,所以需要强转下
        EggDecorator beefNoodleWithEggs =   (EggDecorator)Strategy.get(Strategy.WITH_EGGS);

        System.out.println("只来一碗牛肉面加一个鸡蛋  "+beefNoodleWithEggs.getMsg(1,1)+"价格为:"+ String.valueOf(beefNoodleWithEggs.getPrice(1,1)));

        System.out.println("只来一碗牛肉面加两个鸡蛋  "+beefNoodleWithEggs.getMsg(1,2)+"价格为:"+ String.valueOf(beefNoodleWithEggs.getPrice(1,2)));

        System.out.println("只来两碗碗牛肉面加两个鸡蛋  "+beefNoodleWithEggs.getMsg(2,2)+"价格为:"+ String.valueOf(beefNoodleWithEggs.getPrice(2,2)));


        // 策略模式选择加 香肠的 策略; 要用子类的方法,所以需要强转下
        SausageDecorator beefNoodleWithSausage =   (SausageDecorator)Strategy.get(Strategy.WITH_SAUSAGES);
        System.out.println("只来一碗牛肉面加一个香肠  "+beefNoodleWithSausage.getMsg(1,1)+"价格为:"+ String.valueOf(beefNoodleWithSausage.getPrice(1,1)));

        System.out.println("只来一碗牛肉面加两个香肠  "+beefNoodleWithSausage.getMsg(1,2)+"价格为:"+ String.valueOf(beefNoodleWithSausage.getPrice(1,2)));

        System.out.println("只来两碗碗牛肉面共加两个香肠  "+beefNoodleWithSausage.getMsg(2,2)+"价格为:"+ String.valueOf(beefNoodleWithSausage.getPrice(2,2)));

        //策略模式选择加 鸡蛋和香肠
        EggsAndSausageDecorator beefNoodleWithEggsAndSausages = (EggsAndSausageDecorator)Strategy.get(Strategy.WITH_EGGS_AND_SAUSAGES);


        System.out.println("只来一碗牛肉面加一个鸡蛋一个香肠  "+beefNoodleWithEggsAndSausages.getMsg(1,1,1)+"价格为:"+ String.valueOf(beefNoodleWithEggsAndSausages.getPrice(1,1,1)));

        System.out.println("只来一碗牛肉面加两个鸡蛋两个香肠  "+beefNoodleWithEggsAndSausages.getMsg(1,2,2)+"价格为:"+ String.valueOf(beefNoodleWithEggsAndSausages.getPrice(1,4,4)));

        System.out.println("只来两碗碗牛肉面各加两个鸡蛋两个香肠  "+beefNoodleWithEggsAndSausages.getMsg(2,4,4)+"价格为:"+ String.valueOf(beefNoodleWithEggsAndSausages.getPrice(2,4,4)));

    }
}

 

测试结果:

只来一碗牛肉面牛肉面 * 1价格为:5
只来两碗牛肉面牛肉面 * 2价格为:10
只来一碗牛肉面加一个鸡蛋  牛肉面 * 1加1个鸡蛋价格为:6
只来一碗牛肉面加两个鸡蛋  牛肉面 * 1加2个鸡蛋价格为:7
只来两碗碗牛肉面加两个鸡蛋  牛肉面 * 2加2个鸡蛋价格为:12
只来一碗牛肉面加一个香肠  牛肉面 * 1加1根香肠价格为:6
只来一碗牛肉面加两个香肠  牛肉面 * 2加2根香肠价格为:7
只来两碗碗牛肉面共加两个香肠  牛肉面 * 2加2根香肠价格为:12
只来一碗牛肉面加一个鸡蛋一个香肠  牛肉面 * 1加1个鸡蛋加1根香肠价格为:8
只来一碗牛肉面加两个鸡蛋两个香肠  牛肉面 * 2加2个鸡蛋加2根香肠价格为:17
只来两碗碗牛肉面各加两个鸡蛋两个香肠  牛肉面 * 4加4个鸡蛋加4根香肠价格为:22

 

你可能感兴趣的:(策略模式)