教你用策略枚举消除if-else判断(以支付场景为例子)带给你新的认知,记得收藏哦~

2024-01-03 05:52:39

在这里插入图片描述

😄 19年之后由于某些原因断更了三年,23年重新扬帆起航,推出更多优质博文,希望大家多多支持~
🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志
🎐 个人CSND主页——Micro麦可乐的博客
🐥《Docker实操教程》专栏以最新的Centos版本为基础进行Docker实操教程,入门到实战
🌺《RabbitMQ》本专栏主要介绍使用JAVA开发RabbitMQ的系列教程,从基础知识到项目实战
🌸《设计模式》专栏以实际的生活场景为案例进行讲解,让大家对设计模式有一个更清晰的理解
如果文章能够给大家带来一定的帮助!欢迎关注、评论互动~

项目场景

我们先来思考一个问题,在日常开发中涉及到支付往往并非单纯的一个支付厂商,可能涉及支付宝、微信支付等等,再比如项目中根据用户的类型给予不同的折扣,如果你还在使用if -else来进行支付类型、用户类型判断,那么请认真看完本篇内容,相信能让你有一个新的认识

你是否也这样判断

我们还是以上述场景来模拟一个支付功能,在你们的项目中是否是这样子判断的,前端传递一个支付类型 payType,在业务代码中判断这个类型从而执行对应的厂商支付

        if ("ALIPAY".equals(payType)) {
            //调用支付宝支付
        } else if ("WECHAT_PAY".equals(payType)) {
            //调用微信支付
        } else if ("UNION_PAY".equals(payType)) {
            //调用银联支付
        } else if ...

从代码可以看出,如果设计到很多种支付类型,那么会出现大量的if-else,着实是一件很影响性能的事情,有没有更好的方案可以替代?答案是有的!

使用策略枚举优化

在项目中我们可以使用枚举(enum)来实现策略模式,并通过枚举常量来消除 if-else 语句,使代码更加灵活、可维护和可扩展,还是上述的支付场景,我们如何使用策略枚举更优雅的实现

定义策略枚举,分别定义 ALIPAY、WECHAT_PAY、UNION_PAY 代表支付宝、微信、银联支付

// 定义策略枚举
public enum PaymentStrategyEnum {
    ALIPAY {
        @Override
        public String pay(int amount) {
            System.out.println("使用支付宝支付: " + amount );
            // 具体的支付逻辑
            return "ALIPAY SUCCESS";
        }
    },
    WECHAT_PAY {
        @Override
        public String pay(int amount) {
            System.out.println("使用微信支付:" + amount);
            // 具体的支付逻辑
            return "WECHAT_PAY SUCCESS";
        }
    },
    UNION_PAY {
        @Override
        public String pay(int amount) {
            System.out.println("使用银联支付:" + amount);
            // 具体的支付逻辑
            return "WECHAT_PAY SUCCESS";
        }
    };

    // 定义抽象方法
    public abstract String pay(int amount);
}

定一个通用的调用支付类,传递枚举对象以及支付金额

public class CheckPay {
    public String toPay(PaymentStrategyEnum paymentStrategyEnum, int amount) {
        return paymentStrategyEnum.pay(amount);
    }
}

前端唤起支付使用了哪个厂商的支付,就传递约定好的参数值,这里为了方便我们就直接以 ALIPAY、WECHAT_PAY、UNION_PAY 作为类型参数

演示代码

public class PayServiceTest {
    public static void main(String[] args) {
//        // 在应用中选择支付策略
//        PaymentStrategyEnum alipay = PaymentStrategyEnum.ALIPAY;
//        PaymentStrategyEnum wechatPay = PaymentStrategyEnum.WECHAT_PAY;
//
//        alipay.pay(100);
//        wechatPay.pay(150);
        pay("ALIPAY",100);
        pay("WECHAT_PAY",150);
        pay("UNION_PAY",200);

    }

    public static String pay(String payType, int amount) {
        CheckPay checkPay = new CheckPay();
        return checkPay.toPay(PaymentStrategyEnum.valueOf(payType),amount);
    }
}

最终输出效果
在这里插入图片描述
在这个示例中,通过使用枚举,每个支付方式都被表示为一个枚举常量,并且每个枚举常量都实现了抽象方法 pay。这种方式可以消除传统的 if-else 语句,并通过直接调用枚举常量的方法来执行相应的支付逻辑。如果需要添加新的支付方式,只需简单地在枚举中添加新的常量即可。

学会举一反三

通过上述支付的代码演示,我们可以思考一下针对不同的用户类型,给予不同的优惠折扣是否也可以使用这种模式?来看看简单的代码样列

// 用户类
class User {
    private UserType userType;

    public User(UserType userType) {
        this.userType = userType;
    }

    public double calculateDiscount(double amount) {
        return userType.calculateDiscount(amount);
    }
}

// 用户类型的策略枚举
enum UserType {
    REGULAR {
        @Override
        public double calculateDiscount(double amount) {
            return amount * 0.1;
        }
    },
    PREMIUM {
        @Override
        public double calculateDiscount(double amount) {
            return amount * 0.2;
        }
    };

    // 定义抽象方法
    public abstract double calculateDiscount(double amount);
}

public class Main {
    public static void main(String[] args) {
        double amount = 100.0;
        //这里模拟知道了用户类型
        User regularUser = new User(UserType.REGULAR);
		//User premiumUser = new User(UserType.PREMIUM);
		
        double regularDiscount = regularUser.calculateDiscount(amount);
        //double premiumDiscount = premiumUser.calculateDiscount(amount);
        
        System.out.println("Regular User Discount: " + regularDiscount);
        //System.out.println("Premium User Discount: " + premiumDiscount);
    }
}

总结

使用策略枚举可以很灵活处理各种复杂判断,且可读性与扩展性都比较好,它更像是函数式编程,即传进一个参数,就可以得到对应模式下返回的数值。这样的设计使得系统更具可读性、可维护性,也更符合开放/封闭原则。

文章来源:https://blog.csdn.net/lhmyy521125/article/details/135347840
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。