前言
你是否会遇到这样的需求:
if (money >= 1000) {
if (type == UserType.SILVER_VIP.getCode()) {
System.out.println("白银会员 优惠50元");
result = money - 50;
} else if (type == UserType.GOLD_VIP.getCode()) {
System.out.println("黄金会员 8折");
result = money * 0.8;
} else if (type == UserType.PLATINUM_VIP.getCode()) {
System.out.println("白金会员 优惠50元,再打7折");
result = (money - 50) * 0.7;
} else {
System.out.println("普通会员 不打折");
result = money;
}
//省略n个
我们都应该写过这样的代码,对此我们常常无从下手,有时就不了了之。
下面就分享一下一些if-else的优雅写法的思路。
需求
一个电商系统,当用户消费满1000 金额,可以根据用户VIP等级,享受打折优惠。根据用户VIP等级,计算出用户最终的费用。
普通会员 不打折
白银会员 优惠50元
黄金会员 8折
白金会员 优惠50元,再打7折
编码实现
private static double getResult(long money, int type){
double result = money;
if (money >= 1000) {
if (type == UserType.SILVER_VIP.getCode()) {
System.out.println("白银会员 优惠50元");
result = money - 50;
} else if (type == UserType.GOLD_VIP.getCode()) {
System.out.println("黄金会员 8折");
result = money * 0.8;
} else if (type == UserType.PLATINUM_VIP.getCode()) {
System.out.println("白金会员 优惠50元,再打7折");
result = (money - 50) * 0.7;
} else {
System.out.println("普通会员 不打折");
result = money;
}
}
}
思考:
策略模式
什么是策略模式?
简单的说就是定义一系列的算法,把它们一个个封装起来,并使它们可以相互替换。
编码:
public interface Strategy{
//计费方法
double compute(long money);
}
//普通会员
public class OridinaryStrategy implements Strategy{
@Override
public double compute(long money){
System.out.println("普通会员 不打折");
return money;
}
}
//白银会员
public class SilverStrategy implements Strategy{
@Override
public double compute(long money){
System.out.println("白银会员 不打折");
return money - 50;
}
}
//等等
定义一个Strategy接口,四个子类实现接口,复写自身对应的complute方法。
private static double getResult(long money, int type){
double result = money;
if (money >= 1000) {
if (type == UserType.SILVER_VIP.getCode()) {
result = new SliverStrategy().complute(money);
} else if (type == UserType.GOLD_VIP.getCode()) {
result = new GoldStrategy().complute(money);
} else if (type == UserType.PLATINUM_VIP.getCode()) {
result = new UserStrategy().complute(money);
} else {
result = new OrdinaryStrategy().complute(money);
}
}
}
对应getResult方法,根据type替换为对应的用户VIP策略。我们尝试进一步优化:
private static double getResult(long money, int type){
if( money < 1000){
return money;
}
Strategy strategy;
if (type == UserType.SILVER_VIP.getCode()) {
strategy = new SliverStrategy();
} else if (type == UserType.GOLD_VIP.getCode()) {
strategy = new GoldStrategy();
} else if (type == UserType.PLATINUM_VIP.getCode()) {
strategy = new UserStrategy();
} else {
strategy = new OrdinaryStrategy();
}
return startegy.complute(money);
}
到这里发现,if-else怎么还在?也就是说还没有达到我想要的结果。
工厂模式+策略模式
public interface Strategy{
double complute(long time);
//返回type
int getType();
}
public class OridinaryStrategy implements strategy{
@Override
public double complute(long money){
System.out.println("普通会员 不打折");
return money;
}
@Override
public int getType(){
return UserType.ORIDINARY.getCode();
}
}
...
在Strategy里新增一个getType方法,用来表示该策略的Type值。
工厂类:
public class StrategyFactory{
private Map<Integer, Strategy> map;
public StrategyFactory(){
List<Strategy> strategies = new ArrayList<>();
strategies.add(new OrdinaryStrategy());
strategies.add(new SilverStrategy());
strategies.add(new GoldStrategy());
strategies.add(new PlatinumStrategy());
strategies.add(new PlatinumStrategy());
map = stratgies.stream().collect(Collectors.toMap(Strategy::getType, strategy -> strategy ));
}
public static class Holder {
publicstatic StrategyFactory instance = new StrategyFactory();
}
public static StrategyFactory getInstance() {
return Holder.instance;
}
public Strategy get(Integer type) {
return map.get(type);
}
}
静态内部类单例,单例模式实现的一种。在这里初始化好Strategy,把list转换成map。
效果
private static double getResult(long money, in type){
if( money < 1000 ){
return money;
}
Strategy strategy = StrategyFactory.getInsatnce().get(type);
if( null == startegy ){
//异常
}
return startegy.complute(money);
}
通过一个工厂类,在我们getResult()调用的时候,根据传入的唐渝鹏,即可获得Strategy。
(转)