if灬else优化
需求介绍
传统做法
1、使用工厂 + 策略模式
2、枚举类方法
结语
我们在写代码时,经常不注意就嵌套了好多的if - else语句,少则没事,多则会造成了代码冗余,耦合度低,极大的影响了程序的拓展性,因此设计好代码模式是非常重要的。以下简单的介绍了2种方法,希望对你有所帮助。
需求介绍
假如有以下一个需求:
一个购物系统,当用户消费满1000 元,可以根据用户VIP等级,享受打折优惠。
根据用户VIP等级,计算出用户最终的费用。
普通用户 不打折
白银会员 优惠50元
黄金会员 8折
白金会员 优惠50元,再打7折
传统做法
private static double getPreResult(long money, int type){
double result = money;
if (money >= 1000) {
if (type == UserType.SILVER_VIP) {
System.out.println("白银会员 优惠50元");
result = money - 50;
} else if (type == UserType.GOLD_VIP) {
System.out.println("黄金会员 8折");
result = money * 0.8;
} else if (type == UserType.PLATINUM_VIP) {
System.out.println("白金会员 优惠50元,再打7折");
result = (money - 50) * 0.7;
} else {
System.out.println("普通用户 不打折");
result = money;
}
}
return result;
}
1、使用工厂 + 策略模式
用户类型类:
public class UserType {
//白银会员
public static int SILVER_VIP = 1;
//白金会员
public static int PLATINUM_VIP = 2;
//黄金会员
public static int GOLD_VIP = 3;
//普通用户
public static int PUTONG = 4;
}
策略接口:
public interface Strategy {
//金额
double compute(long money);
//用户type
int getType();
}
普通会员
public class OrdinaryStrategy implements Strategy {
@Override
public double compute(long money) {
System.out.println("普通用户 不打折");
return money;
}
// 添加 type 返回
@Override
public int getType() {
return UserType.PUTONG;
}
白银会员
public class SilverStrategy implements Strategy {
@Override
public double compute(long money) {
System.out.println("白银会员 优惠50元");
return money - 50;
}
// type 返回
@Override
public int getType() {
return UserType.SILVER_VIP;
}
}
黄金会员
public class GoldStrategy implements Strategy {
@Override
public double compute(long money) {
System.out.println(“黄金会员 8折”);
return money * 0.8;
}
// 添加 type 返回
@Override
public int getType() {
return UserType.GOLD_VIP;
}
}
白金会员
public class PlatinumStrategy implements Strategy {
@Override
public double compute(long money) {
System.out.println(“白金会员 优惠50元,再打7折”);
return (money - 50) * 0.7;
}
@Override
public int getType() {
return UserType.PLATINUM_VIP;
}
}
工厂
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 = new HashMap<>();
for (Strategy strategy : strategies) {
map.put(strategy.getType(), strategy);
}
// 等同于上面方法(只能java8用)
//map = strategies.stream().collect(Collectors.toMap(Strategy::getType, strategy -> strategy));
}
public static class Holder {
public static StrategyFactory instance = new StrategyFactory();
}
public static StrategyFactory getInstance() {
return Holder.instance;
}
public Strategy get(Integer type) {
return map.get(type);
}
}
测试类
public class test {
public static void main(String[] args) {
//getResult(50,3);
System.out.println(getResult(1000,3));//800.0
}
private static double getResult(long money, int type) {
if (money < 1000) {
return money;
}
Strategy strategy = StrategyFactory.getInstance().get(type);
if (strategy == null){
throw new IllegalArgumentException("please input right type");
}
return strategy.compute(money);
}
}
2、枚举类方法
package com.rhy.springboot.study.studytest.factoryStrategy;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.HashMap;
import java.util.Map;
@Getter
@AllArgsConstructor
public enum VipTypeEnum {
SILVER_VIP(UserType.SILVER_VIP){
@Override
public double compute(long money) {
System.out.println("白银会员 优惠50元");
return money - 50;
}
},
PLATINUM_VIP(UserType.PLATINUM_VIP){
@Override
public double compute(long money) {
System.out.println("白金会员 优惠50元,再打7折");
return (money - 50) * 0.7;
}
},
GOLD_VIP(UserType.GOLD_VIP) {
@Override
public double compute(long money) {
System.out.println("黄金会员 8折");
return money * 0.8;
}
},
PUTONG(UserType.PUTONG){
@Override
public double compute(long money) {
System.out.println("普通用户 不打折");
return money;
}
};
// 定义枚举类的判断条件类型
private final Integer type;
// 定义一个静态map 加载类时首先既初始化,执行步骤一
private static Map<Integer, VipTypeEnum> map = new HashMap<>();
/**
* 静态代码块,根据类加载顺序,仅在静态变量后进行加载,在步骤一之后进行加载
*/
static {
for (VipTypeEnum demo : VipTypeEnum.values()) {
map.put(demo.getType(), demo);
}
}
/**
* 根据类型查找对应的枚举类
*
* @param type
* @return
*/
public static VipTypeEnum getMethodByType(Integer type) {
// 此处根据自己代码中的类型判断进行判断,是否有相应的枚举,本文限制类型只能为1-3
if (type > 5 || type < 1) {
// 下面是自定义异常,也可以根据需求自定义实现业务
throw new RuntimeException("不支持的类型会员");
}
return map.get(type);
}
/**
* 自定义枚举中请求参数类型信息及数量信息
* 参数的数量以及参数的类型均可根据需要自定义
* @param money
*/
public abstract double compute(long money);
//测试
public static void main(String[] args) {
System.out.println(VipTypeEnum.getMethodByType(3).compute(1000));
}
}