策略模式

策略模式讲求的是策略:多个策略是平等的,究竟使用哪一个策略完全取决于调用者,策略之间切换不需要任何改动

示例:商城会员分为普通会员和VIP会员;普通会员购买东西不打折,VIP会员购买东西打8折;折扣这块就可以抽象为一个策略接口,具体使用哪一种打折完全取决于用户等级

最容易想到的一种实现方式:

package com.whereta.strategy;

/**
 * Vincent 创建于 2016/4/28.
 */
public class MemberDiscount {

    public double discount(int i, float price) {
        if (i == 1) {
            return price;
        } else if (i == 20) {
            return 0.8 * price;
        }
        return -1;
    }

}

如果要新加一种SVIP,那么就要修改代码了

现在看策略模式实现:

package com.whereta.strategy;

/**
 * Vincent 创建于 2016/4/27.
 */
public interface IMember {
    /**
     * 根据不同等级享受不同折扣
     * @param price
     * @return
     */
    double discount(float price);

}
package com.whereta.strategy;

/**
 * Vincent 创建于 2016/4/27.
 */
public class CommonMember implements IMember {
    //普通会员不享受折扣
    public double discount(float price) {
        return price;
    }
}
package com.whereta.strategy;

/**
 * Vincent 创建于 2016/4/27.
 */
public class VIPMember implements IMember {
    //普通会员享受8折
    public double discount(float price) {
        return 0.8 * price;
    }
}
package com.whereta.strategy;

/**
 * Vincent 创建于 2016/4/27.
 * 此处如果实现了IMember接口,那就是代理模式
 */
public class Context {

    private IMember member;

    public Context(IMember member) {
        this.member = member;
    }
    //根据member获取实际需要支付的现金
    public double discount(float price){
        return member.discount(price);
    }


}
package com.whereta.strategy;

/**
 * Vincent 创建于 2016/4/27.
 */
public class Main {
    public static void main(String[] args) {
        Context context=new Context(new CommonMember());
        double cash = context.discount(200f);
        System.out.println("普通会员:"+cash);
        context=new Context(new VIPMember());
        cash = context.discount(200f);
        System.out.println("VIP会员:"+cash);
    }
}

从以上接口看出与代理模式特别相似,但是不同点是Context没有实现IMember接口

现在如果要新加一个SVIP,只要实现IMember接口即可,不需要修改其他两个实现类

现在升级下:策略枚举

package com.whereta.strategy;

/**
 * Vincent 创建于 2016/4/28.
 */
public enum MemberEnum {
    VIP {
        public double discount(float price) {
            return 0.8 * price;
        }
    }, COMMON {
        public double discount(float price) {
            return price;
        }
    };


    public abstract double discount(float price);
}

具体使用:

double discount = MemberEnum.COMMON.discount(23f);

策略枚举适用于很少变动的情况


个人博客:http://www.whereta.com

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