多个if灬else嵌套优化(工厂+枚举类)

我们在写代码时,经常不注意就嵌套了好多的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));
    }
}

结语

本人也是无意间学习到的,把不同的优化方式整理一下免得以后忘记,便于查阅,同时也希望对各位有用。如果本篇博客有任何错误,请批评指教,不胜感激 !❤️

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Andy's

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值