Java使用策略模式代替多个if else,避免代码糅合在一起,降低维护成本和提高阅读观赏性,遵循代码解耦思想
前言:平常开发时,总是避免不了多个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.策略模式写法
策略模式是一种行为设计模式,它允许在运行时选择算法或行为。
核心思想:将算法的选择和使用算法的上下文分离。
主要组成部分:
- 策略接口:定义了一个或多个算法的方法。
- 具体策略类:实现了策略接口中的方法,每个类代表一个具体的算法。
- 上下文类:持有一个策略对象的引用,并在需要时调用该策略对象的方法。
工作原理:
- 客户端根据需要选择一个具体的策略类并实例化它。
- 将实例化的策略对象传递给上下文类。
- 上下文类使用传递进来的策略对象来执行相应的算法。
优点:
- 灵活性:算法可以独立于使用它的客户端而变化。
- 可扩展性:添加新算法时无需修改现有代码。
- 可维护性:每个算法都被封装在自己的类中,使得代码更加清晰和易于维护。
应用场景:
- 当存在多个算法,并且这些算法需要在运行时根据条件进行切换时。
- 当一个算法有多种实现方式,并且这些实现方式需要在不同情况下被选择时。
下面是具体实现方法:
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;}
}
乍一看代码变多了,实际确实是变多了,但是每一个方法都有自己的实现类,业务逻辑拆分开,各自维护互不干扰,其实正常来讲第二种写法就已经够了,但是为了显得自己突出一点,就这么整,每个方法各有各的优点和缺点,就看写的人怎么想了。
程序员的代码是各有各的风格,写的不好不要乱喷,只为了给后来人一点借鉴,我们都是站在巨人的肩膀上前进,希望能帮到你们,喜欢的点个收藏+关注吧,如果你有什么需求无法解决,也可以私聊我,我有空也可以给你写例子或者给你一个方向,比你慢慢摸索的强。
更多推荐
所有评论(0)