如何避免在Java项⽬⾥⼤批量使⽤if-else?
避免⼤批量使⽤if-else
可能初学者都会忽略掉⼀点,其实if-else是⼀种⾯向过程的实现。
那么,如何避免在⾯向对象编程⾥⼤量使⽤if-else呢?
⽹络上有很多解决思路,有⼯⼚模式、策略模式、甚⾄是规则引擎(这个太重了吧)......
这些,都有⼀个共同的缺点,使⽤起来还是过于繁重了。虽说避免出现过多的if-else,但是,却会增加很多额外的类,我总觉得,很不实⽤,只能当做某种模式的学习即可。
可以替换⼤量的if-else语句,且具备较好的可读性与扩展性,同时能显得轻量化,我⽐较推荐使⽤策略枚举来消除if-else。
如何使⽤呢,下⾯先从⼀个业务案例开始说起下——
假如有这样⼀个需求,需实现⼀周七天内分别知道要做事情的备忘功能,这⾥⾯就会涉及到⼀个流程判断,你可能会⽴马想到⽤if-else,那么,可能是会这样实现——
/
/if-else形式判断
public String getToDo(String day){
if("Monday".equals(day)){
......省略复杂语句
return "今天上英语课";
}else if("Tuesday".equals(day)){
.....省略复杂语句
return "今天上语⽂课";
}else if("Wednesday".equals(day)){
......省略复杂语句
return "今天上数学课";
enum怎么用
}else if("Thursday".equals(day)){
......省略复杂语句
return "今天上⾳乐课";
}else if("sunday".equals(day)){
......省略复杂语句
return "今天上编程课";
}else{
此处省略10086⾏......
}
}
这种代码,在业务逻辑⾥,少量还好,若是⼏百个判断呢,可能整块业务逻辑⾥都是满屏if-else,既不优雅也显得很少冗余。
这时,就可以考虑使⽤策略枚举形式来替换这堆⾯向过程的if-else实现了。
⾸先,先定义⼀个getToDo()调⽤⽅法,假如传进的是“星期⼀”,即参数"Monday"。
//策略枚举判断
public String getToDo(String day){
CheckDay checkDay=new CheckDay();
return checkDay.day(DayEnum.valueOf(day));
}
在getToDo()⽅法⾥,通过DayEnum.valueOf("Monday")可获取到⼀个DayEnum枚举元素,这⾥得到的是Monday。
接下来,执⾏checkDay.day(DayEnum.valueOf("Monday")),会进⼊到day()⽅法中,这⾥,通过Do()做了⼀个策略匹配时。注意⼀点,DayEnum.valueOf("Monday")得到的是枚举中的Monday,这样,实质上就是执⾏了
public class CheckDay {
public String day( DayEnum dayEnum) {
Do();
}
}
上⾯的执⾏过程为什么会是这样⼦呢?只有进⼊到DayEnum枚举当中,才知道是怎么回事了——(话外⾳:我第⼀次接触策略模式时,猛地⼀惊,原来枚举还可以这样玩)
public enum DayEnum {
Monday {
@Override
public String toDo() {
......省略复杂语句
return "今天上英语课";
}
},
Tuesday {
@Override
public String toDo() {
......省略复杂语句
return "今天上语⽂课";
}
},
Wednesday {
@Override
public String toDo() {
......省略复杂语句
return "今天上数学课";
}
},
Thursday {
@Override
public String toDo() {
......省略复杂语句
return "今天上⾳乐课";
}
};
public abstract String toDo();
}
在DayEnum枚举属性当中,定义了⼀个实现了toDo()抽象⽅法——
public abstract String toDo();
在每个枚举元素当中,都重写了该toDo()抽象⽅法。这样,当传参DayEnum.valueOf("Monday")流转到Do()时,实质上是去DayEnum枚举⾥到对应Monday定义的枚举元素,然后执⾏其内部重写的toDo()⽅法。⽤if-esle形式表⽰,就类似"Monday".equals(day)匹配为true时,可得到其内部东西。
总结⼀下,策略枚举就是枚举当中使⽤了策略模式,所谓的策略模式,即给你⼀把钥匙,按照某种约定的⽅式,可以⽴马被指引到可以打开的门。例如,我给你的钥匙叫“Monday”,那么,就可以通过约定
⽅式Do(),⽴马到枚举⾥的Monday⼤门,然后进到门⾥,去做想做的事toDo(),其中,每扇门后的房间都有不同的功能,但它们都有⼀个相同抽象功能——toDo(),即各房间共同地⽅都是可以⽤来做⼀些事情的功能,但具体可以什么事情,就各有不同了。在本⽂的案例⾥,每扇⼤门⾥的toDo(),根据不同策略模式可得到不同字符串返回,例如,"今天上英语课"、"今天上语⽂课",等等。
可见,把流程判断抽取到策略枚举当中,还可以把⼀堆判断解耦出来,避免在业务代码逻辑⾥呈现⼀⼤⽚密密⿇⿇冗余的if-else。
这⾥,会出现⼀种情况,即,假如有多个重复共同样功能的判断话,例如,在if-else⾥,是这样——
public String getToDoByIfElse(String day){
if("Monday".equals(day)||"Tuesday".equals(day)||"Wednesday".equals(day)){
......省略复杂语句
return "今天上英语课";
}else if("Thursday".equals(day)){
......
}
}
那么,在策略枚举下应该如何使⽤从⽽避免代码冗余呢?
可以参考⼀下以下思路,设置⼀个内部策略枚举,将有相同功能的外部引⽤指向同⼀个内部枚举元素,这样即可实现调⽤重复功能了——
public enum DayEnum {
//指向内部枚举的同⼀个属性即可执⾏相同重复功能
Monday("星期⼀", Type.ENGLISH),
Tuesday("星期⼆", Type.ENGLISH),
Wednesday("星期三", Type.ENGLISH),
Thursday("星期四", Type.CHINESE);
private final Type type;
private final String day;
DayEnum(String day, Type type) {
this.day = day;
}
String toDo() {
Do();
}
/**
* 内部策略枚举
*/
private enum Type {
ENGLISH {
@Override
public String toDo() {
......省略复杂语句
return "今天上英语课";
}
},
CHINESE {
@Override
public String toDo() {
.
.....省略复杂语句
return "今天上语⽂课";
}
};
public abstract String toDo();
}
}
若要扩展其判断流程,只需要直接在枚举增加⼀个属性和内部toDo(实现),就可以增加新的判断流程了,⽽外部,仍旧⽤同⼀个⼊⼝Do()即可。
可能,会有这样⼀个疑问:为什么在枚举⾥定义⼀个抽象⽅法,会在各个枚举元素⾥实现呢?
这功能就类似⼦类继承⽗类的做法了。DayEnum类似⼀个⽗类,DayEnum枚举⾥的元素就相当是其⼦类。当⽗类⾥定义了抽象⽅法toDo(),其继承的⼦类就会默认实现toDo()⽅法,这样,就会出现枚举
⾥可以这样的写法:
private enum Type {
ENGLISH {
@Override
public String toDo() {
return "今天上英语课";
}
};
public abstract String toDo();
}
我很喜欢在⼤批量if-else⾥使⽤策略枚举来消除替换,总⽽⾔之,使⽤策略枚举可以很灵活处理各种复
杂判断,且可读性与扩展性都⽐较好,它更像是函数式编程,即传进⼀个参数,就可以得到对应模式下返回的数值。
若Java⾥业务逻辑中⼤批量使⽤if-else,则是⾯向过程了,因为业务逻辑⾥的if-else是从上往下⼀个if接⼀个if判断下去的,在各个if上打个断点,debug下去,就明⽩它其实是⾯向过程的。
由此可知,若项⽬⾥有⼤量的if-else话,着实是⼀件很影响性能的事情,虽然这点性能可忽略不计,但有更好的取代⽅案,不是更好吗?
到此这篇关于如何避免在Java项⽬⾥⼤批量使⽤if-else?的⽂章就介绍到这了,更多相关避免⼤批量使⽤if-else内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论