Skip to content

Commit 20b69f5

Browse files
committed
博文
1 parent 64d954e commit 20b69f5

File tree

30 files changed

+7414
-164
lines changed

30 files changed

+7414
-164
lines changed

Elasticsearch面试/6. Lucene全文搜索的原理.md

Whitespace-only changes.

Java基础学习/Java程序员必备:异常的十个关键知识点.md

Lines changed: 499 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 295 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,295 @@
1+
## 前言
2+
代码中如果if-else比较多,阅读起来比较困难,维护起来也比较困难,很容易出bug,接下来,本文将介绍优化if-else代码的八种方案。
3+
4+
5+
![](https://user-gold-cdn.xitu.io/2020/3/7/170b325db76e6d7f?w=1202&h=594&f=png&s=91815)
6+
7+
### 优化方案一:提前return,去除不必要的else
8+
如果if-else代码块包含return语句,可以考虑通过提前return,把多余else干掉,使代码更加优雅。
9+
10+
**优化前:**
11+
12+
```
13+
if(condition){
14+
//doSomething
15+
}else{
16+
return ;
17+
}
18+
```
19+
**优化后:**
20+
21+
```
22+
if(!condition){
23+
return ;
24+
}
25+
//doSomething
26+
```
27+
28+
### 优化方案二:使用条件三目运算符
29+
使用条件三目运算符可以简化某些if-else,使代码更加简洁,更具有可读性。
30+
31+
**优化前:**
32+
```
33+
int price ;
34+
if(condition){
35+
price = 80;
36+
}else{
37+
price = 100;
38+
}
39+
```
40+
优化后:
41+
```
42+
int price = condition?80:100;
43+
```
44+
45+
46+
### 优化方案三:使用枚举
47+
在某些时候,使用枚举也可以优化if-else逻辑分支,按个人理解,它也可以看做一种**表驱动方法**
48+
49+
**优化前:**
50+
51+
```
52+
String OrderStatusDes;
53+
if(orderStatus==0){
54+
OrderStatusDes ="订单未支付";
55+
}else if(OrderStatus==1){
56+
OrderStatusDes ="订单已支付";
57+
}else if(OrderStatus==2){
58+
OrderStatusDes ="已发货";
59+
}
60+
...
61+
```
62+
**优化后:**
63+
64+
先定义一个枚举
65+
```
66+
67+
public enum OrderStatusEnum {
68+
UN_PAID(0,"订单未支付"),PAIDED(1,"订单已支付"),SENDED(2,"已发货"),;
69+
70+
private int index;
71+
private String desc;
72+
73+
public int getIndex() {
74+
return index;
75+
}
76+
77+
public String getDesc() {
78+
return desc;
79+
}
80+
81+
OrderStatusEnum(int index, String desc){
82+
this.index = index;
83+
this.desc =desc;
84+
}
85+
86+
OrderStatusEnum of(int orderStatus) {
87+
for (OrderStatusEnum temp : OrderStatusEnum.values()) {
88+
if (temp.getIndex() == orderStatus) {
89+
return temp;
90+
}
91+
}
92+
return null;
93+
}
94+
}
95+
96+
97+
```
98+
有了枚举之后,以上if-else逻辑分支,可以优化为一行代码
99+
```
100+
String OrderStatusDes = OrderStatusEnum.0f(orderStatus).getDesc();
101+
```
102+
### 优化方案四:合并条件表达式
103+
如果有一系列条件返回一样的结果,可以将它们合并为一个条件表达式,让逻辑更加清晰。
104+
105+
**优化前**
106+
```
107+
double getVipDiscount() {
108+
if(age<18){
109+
return 0.8;
110+
}
111+
if("深圳".equals(city)){
112+
return 0.8;
113+
}
114+
if(isStudent){
115+
return 0.8;
116+
}
117+
//do somethig
118+
}
119+
```
120+
**优化后**
121+
122+
```
123+
double getVipDiscount(){
124+
if(age<18|| "深圳".equals(city)||isStudent){
125+
return 0.8;
126+
}
127+
//doSomthing
128+
}
129+
```
130+
### 优化方案五:使用 Optional
131+
有时候if-else比较多,是因为非空判断导致的,这时候你可以使用java8的Optional进行优化。
132+
133+
**优化前:**
134+
```
135+
String str = "jay@huaxiao";
136+
if (str != null) {
137+
System.out.println(str);
138+
} else {
139+
System.out.println("Null");
140+
}
141+
```
142+
**优化后:**
143+
144+
```
145+
Optional<String> strOptional = Optional.of("jay@huaxiao");
146+
strOptional.ifPresentOrElse(System.out::println, () -> System.out.println("Null"));
147+
```
148+
149+
150+
### 优化方案六:表驱动法
151+
**表驱动法**,又称之为表驱动、表驱动方法。表驱动方法是一种使你可以在表中查找信息,而不必用很多的逻辑语句(if或Case)来把它们找出来的方法。以下的demo,把map抽象成表,在map中查找信息,而省去不必要的逻辑语句。
152+
153+
**优化前:**
154+
155+
```
156+
if (param.equals(value1)) {
157+
doAction1(someParams);
158+
} else if (param.equals(value2)) {
159+
doAction2(someParams);
160+
} else if (param.equals(value3)) {
161+
doAction3(someParams);
162+
}
163+
// ...
164+
```
165+
166+
**优化后:**
167+
168+
```
169+
Map<?, Function<?> action> actionMappings = new HashMap<>(); // 这里泛型 ? 是为方便演示,实际可替换为你需要的类型
170+
171+
// 初始化
172+
actionMappings.put(value1, (someParams) -> { doAction1(someParams)});
173+
actionMappings.put(value2, (someParams) -> { doAction2(someParams)});
174+
actionMappings.put(value3, (someParams) -> { doAction3(someParams)});
175+
176+
// 省略多余逻辑语句
177+
actionMappings.get(param).apply(someParams);
178+
```
179+
180+
### 优化方案七:优化逻辑结构,让正常流程走主干
181+
182+
**优化前:**
183+
```
184+
public double getAdjustedCapital(){
185+
if(_capital <= 0.0 ){
186+
return 0.0;
187+
}
188+
if(_intRate > 0 && _duration >0){
189+
return (_income / _duration) *ADJ_FACTOR;
190+
}
191+
return 0.0;
192+
}
193+
```
194+
**优化后:**
195+
```
196+
public double getAdjustedCapital(){
197+
if(_capital <= 0.0 ){
198+
return 0.0;
199+
}
200+
if(_intRate <= 0 || _duration <= 0){
201+
return 0.0;
202+
}
203+
204+
return (_income / _duration) *ADJ_FACTOR;
205+
}
206+
```
207+
将条件反转使异常情况先退出,让正常流程维持在主干流程,可以让代码结构更加清晰。
208+
209+
### 优化方案八:策略模式+工厂方法消除if else
210+
211+
假设需求为,根据不同勋章类型,处理相对应的勋章服务,优化前有以下代码:
212+
```
213+
String medalType = "guest";
214+
if ("guest".equals(medalType)) {
215+
System.out.println("嘉宾勋章");
216+
} else if ("vip".equals(medalType)) {
217+
System.out.println("会员勋章");
218+
} else if ("guard".equals(medalType)) {
219+
System.out.println("展示守护勋章");
220+
}
221+
...
222+
```
223+
224+
首先,我们把每个条件逻辑代码块,抽象成一个公共的接口,可以得出以下代码:
225+
226+
```
227+
//勋章接口
228+
public interface IMedalService {
229+
void showMedal();
230+
}
231+
```
232+
我们根据每个逻辑条件,定义相对应的策略实现类,可得以下代码:
233+
```
234+
//守护勋章策略实现类
235+
public class GuardMedalServiceImpl implements IMedalService {
236+
@Override
237+
public void showMedal() {
238+
System.out.println("展示守护勋章");
239+
}
240+
}
241+
//嘉宾勋章策略实现类
242+
public class GuestMedalServiceImpl implements IMedalService {
243+
@Override
244+
public void showMedal() {
245+
System.out.println("嘉宾勋章");
246+
}
247+
}
248+
//VIP勋章策略实现类
249+
public class VipMedalServiceImpl implements IMedalService {
250+
@Override
251+
public void showMedal() {
252+
System.out.println("会员勋章");
253+
}
254+
}
255+
```
256+
接下来,我们再定义策略工厂类,用来管理这些勋章实现策略类,如下:
257+
258+
```
259+
//勋章服务工产类
260+
public class MedalServicesFactory {
261+
262+
private static final Map<String, IMedalService> map = new HashMap<>();
263+
static {
264+
map.put("guard", new GuardMedalServiceImpl());
265+
map.put("vip", new VipMedalServiceImpl());
266+
map.put("guest", new GuestMedalServiceImpl());
267+
}
268+
public static IMedalService getMedalService(String medalType) {
269+
return map.get(medalType);
270+
}
271+
}
272+
```
273+
使用了策略+工厂模式之后,代码变得简洁多了,如下:
274+
```
275+
public class Test {
276+
public static void main(String[] args) {
277+
String medalType = "guest";
278+
IMedalService medalService = MedalServicesFactory.getMedalService(medalType);
279+
medalService.showMedal();
280+
}
281+
}
282+
```
283+
284+
285+
## 参考与感谢
286+
- [6个实例详解如何把if-else代码重构成高质量代码](https://blog.csdn.net/qq_35440678/article/details/77939999)
287+
- [如何 “干掉” if...else](https://www.jianshu.com/p/1db0bba283f0)
288+
289+
## 个人公众号
290+
291+
![](https://user-gold-cdn.xitu.io/2019/7/28/16c381c89b127bbb?w=344&h=344&f=jpeg&s=8943)
292+
293+
- 觉得写得好的小伙伴给个点赞+关注啦,谢谢~
294+
- 同时非常期待小伙伴们能够关注我公众号,后面慢慢推出更好的干货~嘻嘻
295+
- github地址:https://github.com/whx123/JavaHome

0 commit comments

Comments
 (0)