【转】消除代码中的 if-else/switch-case
在很多时候,我们代码中会有很多分支,而且分支下面的代码又有一些复杂的逻辑,相信很多人都喜欢用 if-else/switch-case 去实现。做的不好的会直接把实现的代码放在 if-else/switch-case 的分支之下:
switch ( type ) {
case case1:
...
...
break;
case case2:
...
...
break;
case case3:
...
...
break
default:
return null;
}
这样的代码不仅冗长,读起来也非常困难。做的好一点的会把这些逻辑封装成函数然后在分支中调用:
switch ( type ) {
case case1:
return case1Func();
case case2:
return case2Func();
case case3:
return case3Func();
default:
return null;
}
//各个 tab 名称的枚举:
public enum UserRelatedType {
/**
* 说说
*/
SHUOSHUO("说说"), /**
* 日志
*/
RIZHI("日志"), /**
* 发布
*/
ZHAOPIAN("照片"), /**
* 访客
*/
FANGKE(""); private String desc; UserRelatedType(String desc) {
this.desc = desc;
} public String getDesc() {
return desc;
} public void setDesc(String desc) {
this.desc = desc;
}
}
列出 QQ 用户个人中心相关 tab 的代码:
public List<UserRelatedVO> listRelated(UserRelatedQuery query){ UserRelatedType relatedType = UserRelatedType.valueOf(StringUtils.upperCase(query.getType()) );
switch ( relatedType ) {
case SHUOSHUO:
return listRelatedShuoshuo( query );
case RIZHI:
return listRelatedRizhi( query );
case ZHAOPIAN:
return listRelatedZhaopian( query );
case FANGKE:
return listRelatedFangke( query );
default:
return null;
}
}
而采用注解+策略模式+简单工厂,重构后代码如下:
- 1、定义一个注解,用来完全消除 if-else:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface RelatedTypeAnnotation {
/**
* 用户相关类型名称
*/
UserRelatedType value();
}
- 2、先定义了个接口,所有 tab 都要实现该接口。其中 list 是 tab 数据展示的方法。
public interface UserRelated { /**
* 列出详细信息
*
* @param query
* @return
*/
List<UserRelatedVO> list(UserRelatedQuery query);
}
- 3、定义具体的各个 tab 的实现,继承 UserRelated 策略接口
我的说说
@Component("userRelatedShuoshuo")
@RelatedTypeAnnotation( value = UserRelatedType.SHUOSHUO )
public class UserRelatedShuoshuo implements UserRelated {
@Override
public List<UserRelatedVO> list(UserRelatedQuery query) {
System.out.println("我的说说!");
return list;
}
}
我的日志
@Component("userRelatedRizhi")
@RelatedTypeAnnotation( value = UserRelatedType.RIZHI )
public class UserRelatedRizhi implements UserRelated {
@Override
public List<UserRelatedVO> list(UserRelatedQuery query) {
System.out.println("我的日志!");
return list;
}
}
我的照片
@Component("userRelatedZhaopian")
@RelatedTypeAnnotation( value = UserRelatedType.ZHAOPIAN )
public class UserRelatedZhaopian implements UserRelated {
@Override
public List<UserRelatedVO> list(UserRelatedQuery query) {
System.out.println("我的照片!");
return list;
}
}
我的访客
@Component("userRelatedFangke")
@RelatedTypeAnnotation( value = UserRelatedType.FANGKE )
public class UserRelatedFangke implements UserRelated {
@Override
public List<UserRelatedVO> list(UserRelatedQuery query) {
System.out.println("我的访客!");
return list;
}
}
- 3、定义一个从 Spring context 获取 bean 的工具类
@Component
public class SpringContextUtil implements ApplicationContextAware { private ApplicationContext context; public ApplicationContext getContext() {
return context;
} @Override
public void setApplicationContext(ApplicationContext context)throws BeansException {
this.context = context;
}
}
- 4、定义一个简单工厂,用来生产各种 tab 对象。
@Component
public class UserRelatedFactory { @Autowired
SpringContextUtil springContextUtil; private static Map<UserRelatedType, UserRelated> userRelatedMap = Maps.newConcurrentMap(); //工厂将 Spring 装配的相关的 Bean 用 Map 保存起来
public UserRelatedFactory(){
Map<String, Object> beanMap = springContextUtil.getContext().getBeansWithAnnotation(RelatedTypeAnnotation.class); for(Object userRelated : beanMap.values()) {
RelatedTypeAnnotation annotation = userRelated.getClass().getAnnotation(RelatedTypeAnnotation.class);
userRelatedMap.put(annotation.value(), (UserRelated)userRelated);
}
} public static UserRelated createRelated(UserRelatedType relatedType) {
return userRelatedMap.get( relatedType );
}
}
5、调用的代码(listRelated 会在 controller 中被调用)。
public List<UserRelatedVO> listRelated(UserRelatedQuery query){ UserRelatedType relatedType = UserRelatedType.valueOf(StringUtils.upperCase(query.getType()) );
UserRelated related = UserRelatedFactory.createRelated( relatedType );
if( related != null ) {
return related.list( query );
} else {
return null;
}
}
重构后的代码如果需要再新增一种 tab,比如我的好友,只需要新增一种类型继承 UserRelated 实现其中的 list,并加上相应的注解即可。
链接:https://juejin.im/post/5ca9f113e51d452b5e458ec3
来源:掘金
【转】消除代码中的 if-else/switch-case的更多相关文章
- Java-Annotation的一种用法(消除代码中冗余的if/else或switch语句)
Java-Annotation的一种用法(消除代码中冗余的if/else或switch语句) 1.冗余的if/else或switch 有没有朋友写过以下的代码结构,大量的if/esle判断,来选择 ...
- 使用Java8中的Optional类来消除代码中的null检查
简介 Optional类是Java 8新增的一个类,Optional 类主要解决的问题是臭名昭著的空指针异常(NullPointerException). —— 每个 Java 程序员都非常了解的异常 ...
- java中的分支结构 switch case的使用
switch(A),括号中A的取值只能是整型或者可以转换为整型的数值类型,比如byte.short.int.char.string(jdk1.7后加入)还有枚举:需要强调的是:long是不能用在swi ...
- Dreamweaver中清除php代码中多余空行的方法
使用DW自带的搜索功能,利用正则表达式 使用正则表达式搜索:\r\n\s*\r\n即可搜到代码中的空行,再用回车符\n替换即可消除代码中的多余空行
- 为什么说在使用多条件判断时switch case语句比if语句效率高?
在学习JavaScript中的if控制语句和switch控制语句的时候,提到了使用多条件判断时switch case语句比if语句效率高,但是身为小白的我并没有在代码中看出有什么不同.去度娘找了半个小 ...
- C# 利用键值对取代Switch...Case语句
swich....case 条件分支多了之后,会严重的破坏程序的美观性. 比如这个 上述代码是用于两个进程之间通信的代码,由于通信的枚举特别的多,所以case的分支特别的多.导致了代码的可读性,可维护 ...
- 知识扩展--if...else...与switch...case...的执行原理
一.简述 编程语言中的条件分支结构有两种:if-else和switch-case,这两种条件分支之间可以相互转换,但是也存在一些区别,那么什么时候该用if-else,什么时候该用switch-case ...
- switch case 与 if
case 在编程中偶尔使用到switch case语句,对于case语句的处理,出现了两种错误,现总结如下: case后必须是常量.布尔类型.字符(不能是字符串): case后如果是‘||’或者‘&a ...
- Java代码消除switch/case,if/else语句的几种实现方式
转自:https://my.oschina.net/stefanzhlg/blog/372413 我们在平时的编码中,我们经常会遇到这样的情况: 使用过多的switch/case 或者 if else ...
随机推荐
- Visualizing the Git data model
I wrote a small tool git-graph.py over the weekend which can be used to generate the object graph of ...
- 【渗透攻防Web篇】SQL注入攻击高级
前言 前面我们学习了如何寻找,确认,利用SQL注入漏洞的技术,本篇文章我将介绍一些更高级的技术,避开过滤,绕开防御.有攻必有防,当然还要来探讨一下SQL注入防御技巧. 目录 第五节 避开过滤方法总结 ...
- less编译工具——koala使用介绍
1:使用koala编译软件 官网:http://koala-app.com/index-zh.html (目前官网点击下载没有反应,有人说可能是网络问题,但真正的原因是需要FQ才能下载了) 百度 ...
- Oracle递归查询start with connect by prior
一.基本语法 connect by递归查询基本语法是: select 1 from 表格 start with ... connect by prior id = pId start with:表示以 ...
- [原创]K8Cscan插件之端口扫描C#源码
[原创]K8 Cscan 大型内网渗透自定义扫描器 https://www.cnblogs.com/k8gege/p/10519321.html Cscan简介:何为自定义扫描器?其实也是插件化,但C ...
- python之N阶乘结果末尾有几个0
算法思路:首先是算阶乘,可以使用内置函数reduce实现,其次是计算结果的末尾有几个0,可以使用除余判断 代码如下: #!/usr/bin/env python#-*-coding:utf-8-*- ...
- 【ABP杂烩】Extensions后缀扩展方法
1.Extensions介绍 扩展方法使你能够向现有类型“添加”方法,而无需创建新的派生类型.重新编译或以其他方式修改原始类型. 扩展方法是一种特殊的静态方法,但可以像扩展类型上的实例方法一样进行调用 ...
- 2015 CALLED THE INTERFACE OF 2014
Writer:BYSocket(泥沙砖瓦浆木匠) 微博:BYSocket 豆瓣:BYSocket Reprint it anywhere u want. ”Hi , Happy New Year.Wr ...
- Chapter 4 Invitations——2
To my dismay, I found myself the center of attention for the rest of that week. 令我沮丧的是, 我发现我自己剩余注意力的 ...
- 函数式编程之-初窥F#
大量讲解函数式编程语言的书籍最终都会用Fuctor,Monad,Monoids,范畴论等各种词汇吓退命令式语言玩家,所以我试图避开这些问题,揭开这些复杂词汇带来的具有实战意义的成果.另外我会尽量使用C ...