前言:平常开发时,总是避免不了多个if else判断,执行不同的业务逻辑,通常写法基本都是糅合在一起,显得代码又臭又长,维护成本很高,也不美观,修改部分业务逻辑,整体业务模块都要重新测一遍,大大的提高了工作量。话不多说,代码开整


需求:前端传一个userFrom类型,此类型为:1:入驻码,2:引流码,3:自然流量,:4医生推荐,5:引流人推荐,后台需求需要根据不同类型执行相应的业务逻辑,每个类型的业务逻辑都不一样。


1.新手写法

    public int bindDoctorw(BindDoctorRequest dindDoctorRequest) {
        if(dindDoctorRequest.getUserFrom()==1){
            //执行业务代码
        }else if(dindDoctorRequest.getUserFrom()==2){
            //执行业务代码
        }else if(dindDoctorRequest.getUserFrom()==3){
            //执行业务代码
        }else if(dindDoctorRequest.getUserFrom()==4){
            //执行业务代码
        }else if(dindDoctorRequest.getUserFrom()==5){
            //执行业务代码
        }
        return 0;
    }

具体业务代码就不写了,要是都糅合在一起,自己想象一下bindDoctorw方法有多长,虽然看起来流程步骤很清晰,但是维护成本变高了,所以这种方法是不可取的,要是你是干外包的项目请移步,外包的要求还那么多?这样就行了。


2.代码解耦拆分写法

   public int bindDoctorw(BindDoctorRequest dindDoctorRequest) {
        if(dindDoctorRequest.getUserFrom()==1){
            //执行业务代码
            UserFrom1(dindDoctorRequest);
        }else if(dindDoctorRequest.getUserFrom()==2){
            //执行业务代码
            UserFrom2(dindDoctorRequest);
        }else if(dindDoctorRequest.getUserFrom()==3){
            //执行业务代码
            UserFrom3(dindDoctorRequest);
        }else if(dindDoctorRequest.getUserFrom()==4){
            //执行业务代码
            UserFrom4(dindDoctorRequest);
        }else if(dindDoctorRequest.getUserFrom()==5){
            //执行业务代码
            UserFrom5(dindDoctorRequest);
        }
    }

  
     public int UserFrom1(BindDoctorRequest dindDoctorRequest) {
   
    }
     public int UserFrom2(BindDoctorRequest dindDoctorRequest) {
   
    }
     public int UserFrom3(BindDoctorRequest dindDoctorRequest) {
   
    }
     public int UserFrom4(BindDoctorRequest dindDoctorRequest) {
   
    }
     public int UserFrom5(BindDoctorRequest dindDoctorRequest) {
   
    }

或者这种写法

   public int bindDoctorw(BindDoctorRequest dindDoctorRequest) {
          switch (dindDoctorRequest.getUserFrom()){
            case 1:
                //执行业务代码
                UserFrom1();
                break;
            case 2:
                //执行业务代码
                UserFrom2();
                break;
            case 3:
                //执行业务代码
                UserFrom3();
                break;
            case 4:
                //执行业务代码
                UserFrom4();
                break;
            case 5:
                //执行业务代码
                UserFrom5();
                break;
        }
    }

  
     public int UserFrom1(BindDoctorRequest dindDoctorRequest) {
   
    }
     public int UserFrom2(BindDoctorRequest dindDoctorRequest) {
   
    }
     public int UserFrom3(BindDoctorRequest dindDoctorRequest) {
   
    }
     public int UserFrom4(BindDoctorRequest dindDoctorRequest) {
   
    }
     public int UserFrom5(BindDoctorRequest dindDoctorRequest) {
   
    }

这种看起来要比第一种美观多了,把对应的业务逻辑解耦拆分,每次业务变动只需要变动对应类型方法的业务就行,维护成本大大降低,但是有没有更好的写法呢?那肯定是有的,这里就要讲到策略模式写法


3.策略模式写法

策略模式是一种行为设计模式,它允许在运行时选择算法或行为。

核心思想:将算法的选择和使用算法的上下文分离。

主要组成部分

  1. 策略接口:定义了一个或多个算法的方法。
  2. 具体策略类:实现了策略接口中的方法,每个类代表一个具体的算法。
  3. 上下文类:持有一个策略对象的引用,并在需要时调用该策略对象的方法。

工作原理

  • 客户端根据需要选择一个具体的策略类并实例化它。
  • 将实例化的策略对象传递给上下文类。
  • 上下文类使用传递进来的策略对象来执行相应的算法。

优点

  • 灵活性:算法可以独立于使用它的客户端而变化。
  • 可扩展性:添加新算法时无需修改现有代码。
  • 可维护性:每个算法都被封装在自己的类中,使得代码更加清晰和易于维护。

应用场景

  • 当存在多个算法,并且这些算法需要在运行时根据条件进行切换时。
  • 当一个算法有多种实现方式,并且这些实现方式需要在不同情况下被选择时。

下面是具体实现方法:

3.1 提供一个service实现类,用于外部controller调用

 @Override
    public int bindDoctor(BindDoctorRequest dindDoctorRequest) {
        UserFromImplementsStrategy entryStrategy = 
        FromTypeStrategyFactory.getStrategy(dindDoctorRequest.getUserFrom());
        return entryStrategy.execute(dindDoctorRequest);
    }

3.2 定义策略接口

/**
 * 用户来源策略
 */
public interface UserFromImplementsStrategy {
    int execute(BindDoctorRequest request);
}

3.3 实现具体的策略类

/**
 * 医生推荐策略处理逻辑
 */
public class DoctorReferralStrategy implements UserFromImplementsStrategy {
    @Override
    public int execute(BindDoctorRequest request) {
        //执行具体的业务逻辑
        return Constants.SUCCESS_CODE;
    }
/**
 * 入驻码策略处理逻辑
 */
public class EntryCodeStrategy implements UserFromImplementsStrategy {
    @Override
    public int execute(BindDoctorRequest request) {
        //执行具体的业务逻辑
        return Constants.SUCCESS_CODE;
    }
/**
 * 引流码策略处理逻辑
 */
public class LeadCodeStrategy implements UserFromImplementsStrategy {
    @Override
    public int execute(BindDoctorRequest request) {
        //执行具体的业务逻辑
        return Constants.SUCCESS_CODE;
    }
/**
 * 引流人推荐策略处理逻辑
 */
public class LeadReferrerStrategy implements UserFromImplementsStrategy {
    @Override
    public int execute(BindDoctorRequest request) {
        //执行具体的业务逻辑
        return Constants.SUCCESS_CODE;
    }

}
public class NaturalFlowStrategy implements UserFromImplementsStrategy {
    @Override
    public int execute(BindDoctorRequest request) {
        //执行具体的业务逻辑
        return Constants.SUCCESS_CODE;
    }
}
/**
 * 医生推荐策略处理逻辑
 */
public class NutritionistStrategy implements UserFromImplementsStrategy {
    @Override
    public int execute(BindDoctorRequest request) {
        //执行具体的业务逻辑
        return Constants.SUCCESS_CODE;
    }
}

3.4 创建策略工厂

public class FromTypeStrategyFactory {
    public static UserFromImplementsStrategy getStrategy(Long userfromType) {
        if (userfromType == UserFromEnum.ENTER_CODE_TYPE.getCode()) {
            return new EntryCodeStrategy();
        } else if (userfromType == UserFromEnum.DRIVE_CODE_TYPE.getCode()) {
            return new LeadCodeStrategy();
        } else if (userfromType == UserFromEnum.DRIVE_CODE_RECOMMEND_TYPE.getCode()) {
            return new NaturalFlowStrategy();
        } else if (userfromType == UserFromEnum.DOCTOR_CODE_RECOMMEND_TYPE.getCode()) {
            return new DoctorReferralStrategy();
        } else if (userfromType == UserFromEnum.DOCTOR_CODE_TYPE.getCode()) {
            return new LeadReferrerStrategy();
        }else if (userfromType == UserFromEnum.NUTRITIONIST_CODE_TYPE.getCode()) {
            return new NutritionistStrategy();
        }
        throw new BaseException("Unknown code type: " + userfromType);
    }
}



public enum UserFromEnum {
    //1入驻码2引流码3自然流量4医生推荐5引流人推荐6营养师列表绑定
    ENTER_CODE_TYPE(1L,"入驻码"),
    DRIVE_CODE_TYPE(2L,"引流码"),
    DRIVE_CODE_RECOMMEND_TYPE(3L,"自然流量"),
    DOCTOR_CODE_RECOMMEND_TYPE(4L,"医生推荐"),
    DOCTOR_CODE_TYPE(5L,"引流人推荐"),
    NUTRITIONIST_CODE_TYPE(6L,"营养师列表绑定"),
    ;
    private final Long code;
    private final String message;
    UserFromEnum(Long code, String message) {
        this.code = code;
        this.message = message;
    }
    public Long getCode() {return code;}
    public String getMessage() {return message;}
}

乍一看代码变多了,实际确实是变多了,但是每一个方法都有自己的实现类,业务逻辑拆分开,各自维护互不干扰,其实正常来讲第二种写法就已经够了,但是为了显得自己突出一点,就这么整,每个方法各有各的优点和缺点,就看写的人怎么想了。


程序员的代码是各有各的风格,写的不好不要乱喷,只为了给后来人一点借鉴,我们都是站在巨人的肩膀上前进,希望能帮到你们,喜欢的点个收藏+关注吧,如果你有什么需求无法解决,也可以私聊我,我有空也可以给你写例子或者给你一个方向,比你慢慢摸索的强。

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐