代码中如何干掉太多的if else即if else的多种替代方案以提高代码质量通过公司代码审查

7 篇文章 14 订阅
3 篇文章 0 订阅


感兴趣的小伙伴可以看看小编其他文章

微服务 分布式 集群 负载均衡详述

使用高并发利器redis—解决淘宝/微博的【热门搜索】和【最近搜索】的功能

2.5万字详解Java 23种设计模式的简介和创建型模式(简单工厂、工厂方法、抽象工厂、单例-多线程安全详解、建造者、原型)的详细解读、UML类图、及代码演示

MySQL查询语句执行顺序以及各关键字的详解

前言

if…else

if…else控制语句,如果代码里滥用会大大降低代码的可读性、可维护性、可扩展性以及灵活性,进而使整个软件系统造成危害。因为在实际的项目中,需求往往是不断变化的,新需求也层出不穷,因此违反了违反单一职责原则和开闭原则,而且有些公司的代码审查会通不过。所以,if else的替代方案是很有必要的,如位语句,枚举,工厂模式,策略模式,状态模式等等
这里用一个场景详细说明if else的替代方案,大家用支付宝付款的时候,会有多种付款方式,如余额,花呗,余额宝,信用卡,银行卡。。。

传统的方式

public class PayDemo {

    public String pay(String payType) {

        String pay = "";
        if ("1".equals(payType)) {
            pay = "支付宝余额支付";
        } else if ("2".equals(payType)) {
            pay = "支付宝余额宝支付";
        } else if ("3".equals(payType)) {
            pay = "支付宝花呗支付";
        } else {
            pay = "其他支付";
        }
        //...
        System.out.println(pay);
        return pay;
    }
}

```java
public class PayTest {
    public static void main(String[] args) {
        PayDemo payDemo = new PayDemo();
        payDemo.pay("1");
        payDemo.pay("2");
        payDemo.pay("3");
        payDemo.pay("4");
    }
}

枚举第一种

(1)面向接口编程,首先定义一个支付接口

public interface PayEnum {
    String pay();
}

(2)定义一个具体的支付宝余额实现

public class PayEnumByBalance implements PayEnum{

    @Override
    public String pay() {
        System.out.println("支付宝余额支付");
        return "支付宝余额支付";
    }
}

(3)定义一个具体的支付宝花呗实现

public class PayEnumByHuabei implements PayEnum {
    @Override
    public String pay() {
        System.out.println("支付宝花呗支付");
        return "支付宝花呗支付";
    }
}

(4)定义一个具体的支付宝余额宝实现

public class PayEnumByYuEBAO implements PayEnum {

    @Override
    public String pay() {
        System.out.println("支付宝余额宝支付");
        return "支付宝余额宝支付";
    }
}

(5)定义一个枚举类

public enum PayTypeEnum {

    PAY_BALANCE("1",new PayEnumByBalance()),
    PAY_HUABEI("2",new PayEnumByHuabei()),
    PAY_YUEBAO("3",new PayEnumByYuEBAO());

    private String payType;
    private PayEnum payEnum;

    PayTypeEnum(String payType, PayEnum payEnum) {
        this.payType = payType;
        this.payEnum = payEnum;
    }

    public static PayEnum getPay(String payType){
        for (PayTypeEnum payTypeEnum : PayTypeEnum.values()) {
            if (payTypeEnum.payType.equals(payType)) {
                return payTypeEnum.payEnum;
            }
        }
        return new PayEnumByBalance();
    }
}

(6)客户端

public class PayEnumTest {
    public static void main(String[] args) {

        PayEnum payEnum = PayTypeEnum.getPay("1");
        payEnum.pay();
        PayEnum payEnum1 = PayTypeEnum.getPay("2");
        payEnum1.pay();
        PayEnum payEnum2 = PayTypeEnum.getPay("3");
        payEnum2.pay();
    }
}

(7)结果:
在这里插入图片描述
(8)总结:完全消除了if else

枚举第二种

(1)面向接口编程,首先定义一个支付接口

public interface PayEnum1 {
    String pay();
}

(2)定义一个枚举类,并且实现支付接口

public enum PayTypeEnum1 implements PayEnum1{

    PAY_TYPE_BALANCE{
        @Override
        public String pay() {
            System.out.println("支付宝余额支付");
            return "支付宝余额支付";
        }
    },
    PAY_TYPE_HUABEI{
        @Override
        public String pay() {
            System.out.println("支付宝花呗支付");
            return "支付宝花呗支付";
        }
    },
    PAY_TYPE_YUEBAO{
        @Override
        public String pay() {
            System.out.println("支付宝余额宝支付");
            return "支付宝余额宝支付";
        }
    };
}

(3)客户端代码

public class PayEnum1Test {
    
    public static void main(String[] args) {
        PayEnum1Test payEnum1Test = new PayEnum1Test();
        payEnum1Test.pay("PAY_TYPE_BALANCE");
        payEnum1Test.pay("PAY_TYPE_HUABEI");
        payEnum1Test.pay("PAY_TYPE_YUEBAO");
    }
    
    public String pay(String payType){
        return PayTypeEnum1.valueOf(payType).pay();
    }
}

(4)结果:
在这里插入图片描述
(5)总结
根据业务场景,如果代码业务量少,可以用枚举第二种,如果代码业务量大,可以用枚举第一种。都可以解决if else代码。

工厂模式

public interface PayFactory {
    String pay();
}

public class PayFactoryByBalance implements PayFactory {

    @Override
    public String pay() {
        System.out.println("支付宝余额支付");
        return "支付宝余额支付";
    }
}

public class PayFactoryByHuabei implements PayFactory {

    @Override
    public String pay() {
        System.out.println("支付宝花呗支付");
        return "支付宝花呗支付";
    }
}

public class PayFactoryByYuEBAO implements PayFactory {

    @Override
    public String pay() {
        System.out.println("支付宝余额宝支付");
        return "支付宝余额宝支付";
    }
}
public class PayTypeFactory {

    private static Map<String,PayFactory> payTypeMap = new HashMap<>();

    static {
        payTypeMap.put("1",new PayFactoryByBalance());
        payTypeMap.put("2",new PayFactoryByHuabei());
        payTypeMap.put("3",new PayFactoryByYuEBAO());
    }

    public static PayFactory getPayType(String payType){
        return payTypeMap.get(payType);
    }

}
public class PayFactoryTest {
    public static void main(String[] args) {
        PayTypeFactory.getPayType("1").pay();
        PayTypeFactory.getPayType("2").pay();
        PayTypeFactory.getPayType("3").pay();
    }
}

结果:
在这里插入图片描述

策略模式+工厂模式

策略模式一句话就是,定义一系列算法,把他们封装起来,并且使它们可以相互替换。具体来说就说,定义多个策略对象,每个策略对象里面封装好多种算法,再定义一个上下文对象,该上下文对象负责根据传入不同的策略对象,执行不同的行为。
(1)定义一个抽象的公共策略接口Strategy,通常为接口,定义每个策略或算法必须具有的方法和属性。

public interface PayStrategy {
    String pay();
}

(2)定义一个context对象,即扮演一个上下的文角色,起承上启下的封装作用,其行为随着策略对象改变而改变。

public class PayContext {

    private PayStrategy payStrategy;

    public PayContext(PayStrategy payStrategy) {
        this.payStrategy = payStrategy;
    }

    public String executeStrategy(){
        return payStrategy.pay();
    }
}

(3)定义一个具体的余额支付策略

public class PayStrategyByBalance implements PayStrategy {
    @Override
    public String pay() {
        System.out.println("支付宝余额支付");
        return "支付宝余额支付";
    }
}

(4)定义一个具体的花呗支付策略

public class PayStrategyByHuabei implements PayStrategy {
    @Override
    public String pay() {
        System.out.println("支付宝花呗支付");
        return "支付宝花呗支付";
    }
}

(5)定义一个具体的余额宝支付策略

public class PayStrategyByYuEBAO implements PayStrategy {
    @Override
    public String pay() {
        System.out.println("支付宝余额宝支付");
        return "支付宝余额宝支付";
    }
}

(6)客户端

public class PayStrategyTest {
    
    public static void main(String[] args) {
        PayStrategyTest payStrategyTest = new PayStrategyTest();
        payStrategyTest.method("1");
        payStrategyTest.method("2");
        payStrategyTest.method("3");
    }

    public void method(String payType){

        PayContext payContext;
        if ("1".equals(payType)){
            payContext = new PayContext(new PayStrategyByHuabei());
            payContext.executeStrategy();

        }else if ("2".equals(payType)){
            payContext = new PayContext(new PayStrategyByYuEBAO());
            payContext.executeStrategy();

        }else if ("3".equals(payType)){
            payContext = new PayContext(new PayStrategyByBalance());
            payContext.executeStrategy();

        }
    }
    
}

(7)结果:
在这里插入图片描述
此时只有策略模式,还没有加入工厂模式
(8)定义一个策略工厂类

public class PayStrategyFactory {

    private static Map<String, PayStrategy> payTypeMap = new HashMap<>();

    static {
        payTypeMap.put("1",new PayStrategyByBalance());
        payTypeMap.put("2",new PayStrategyByYuEBAO());
        payTypeMap.put("3",new PayStrategyByHuabei());
    }

    public static PayStrategy getPayType(String payType){
        return payTypeMap.get(payType);
    }
}

(9)再看客户端代码

public class PayStrategyFactoryTest {
    public static void main(String[] args) {

        PayContext payContext = new PayContext(PayStrategyFactory.getPayType("1"));
        payContext.executeStrategy();

        PayContext payContext2 = new PayContext(PayStrategyFactory.getPayType("2"));
        payContext2.executeStrategy();

        PayContext payContext3 = new PayContext(PayStrategyFactory.getPayType("3"));
        payContext3.executeStrategy();
    }
}

运行结果还是一样的就不看了哈

状态模式+工厂模式

状态模式一句话来说就是,允许一个对象在其对象内部状态改变时改变它的行为。具体来讲,定义多种状态对象,和定义一个行为随着状态对象改变而改变的 context 对象。
(1)面向接口编程,定义一个支付接口

public interface PayState {
    String pay(PayContext payContext);
}

(2)定义一个context上下文

public class PayContext {

    private PayState payState;

    public PayContext() {
        this.payState = null;
    }

    public void setPayState(PayState payState) {
        this.payState = payState;
    }

    public PayState getPayState() {
        return payState;
    }
}

(2)定义具体的状态类

public class PayStateByBalance implements PayState {
    @Override
    public String pay(PayContext payContext) {
        System.out.println("支付宝余额支付");
        payContext.setPayState(this);
        return "支付宝余额支付";
    }
}
public class PayStateByHuabei implements PayState {
    @Override
    public String pay(PayContext payContext) {
        System.out.println("支付宝花呗支付");
        payContext.setPayState(this);
        return "支付宝花呗支付";
    }
}
public class PayStateByYuEBAO implements PayState {

    @Override
    public String pay(PayContext payContext) {
        System.out.println("支付宝余额宝支付");
        payContext.setPayState(this);
        return "支付宝余额宝支付";
    }
}

(3)客户端

public class PayStateTest {
    
    public static void main(String[] args) throws InterruptedException {
        /**使用 Context 来查看当状态 State 改变时的行为变化。
         * 使用 Context 和状态对象来演示 Context 在状态改变时的行为变化。*/
        PayStateTest payStateTest = new PayStateTest();
        payStateTest.method("1");
        payStateTest.method("2");
        payStateTest.method("3");
    }

    public void method(String payType){
        PayContext context = new PayContext();

        if ("1".equals(payType)) {
            PayStateByBalance payStateByBalance = new PayStateByBalance();
            payStateByBalance.pay(context);
        }else if("2".equals(payType)) {
            PayStateByHuabei payStateByHuabei = new PayStateByHuabei();
            payStateByHuabei.pay(context);
        }else if("3".equals(payType)) {
            PayStateByYuEBAO payStateByYuEBAO = new PayStateByYuEBAO();
            payStateByYuEBAO.pay(context);
        }
    }
}

(4)结果:
在这里插入图片描述
此时仅仅是状态模式,没有彻底取消if else
(5)加入工厂模式

public class PayStateFactory {
    private static Map<String, PayState> payTypeMap = new HashMap<>();

    static {
        payTypeMap.put("1",new PayStateByBalance());
        payTypeMap.put("2",new PayStateByYuEBAO());
        payTypeMap.put("3",new PayStateByHuabei());
    }

    public static PayState getPayType(String payType){
        return payTypeMap.get(payType);
    }
}

(6)再看客户端代码

public class PayStateFactoryTest {
    
    public static void main(String[] args) {
        PayContext context = new PayContext();
        PayStateFactory.getPayType("1").pay(context);
        PayStateFactory.getPayType("2").pay(context);
        PayStateFactory.getPayType("3").pay(context);
    }
}

总结:完全解决了代码中的if else,代码看起来非常漂亮,公司的代码审查终于通过辣,太棒啦!!!

对设计模式不是很理解的童靴可以看小编另一篇文章
2.5万字详解Java 23种设计模式的简介和创建型模式(简单工厂、工厂方法、抽象工厂、单例-多线程安全详解、建造者、原型)的详细解读、UML类图、及代码演示

感兴趣的小伙伴可以看看小编其他文章
微服务 分布式 集群 负载均衡详述

MySQL查询语句执行顺序以及各关键字的详解

  • 27
    点赞
  • 98
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

王德印

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

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

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

打赏作者

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

抵扣说明:

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

余额充值