我們知道因為編程語言的限制,歷史遺留下來的系統(tǒng)總是有很多的毛病,不夠面向?qū)ο螅绕涫呛芏嘞到y(tǒng)濫用if else。我曾經(jīng)見過一個項目,大家基本上就是寫一個方法,然后在里面if else套if esle得嵌套了好幾層,難看就不必說了,這種代碼根本就沒法維護(hù)。
今天我就使用從實際項目中提煉出來的例子來講解一下如何將這類代碼變得更加面向?qū)ο?- 重構(gòu)成模式并且添加測試代碼,
先來看一個丑陋的類:
這里我們展示了一個 SystemManager,它負(fù)責(zé)處理用戶在系統(tǒng)中的狀態(tài):登入(logged in),登出(logged out),以及空閑(idle)。從代碼中可以看到,這個類用了int來定義狀態(tài)并且因此導(dǎo)致了updatteState()方法里面出現(xiàn)大量if else。從目前看來這些if else是無法避免的,應(yīng)為這個類需要針對不同的狀態(tài)作出反應(yīng)。隨著狀態(tài)的增加,if else的數(shù)量也會繼續(xù)增加。這個解決方案顯然很差。
那么怎么樣才能讓這個類更加地面向?qū)ο竽兀?br id="i7km89" />
在處理面向?qū)ο笾埃覀兪紫纫帉懸粋€測試類,這也是處理這類歷史遺留下來代碼所必需做的第一步,只有在測試代碼的保護(hù)下,我們才能放心大膽地進(jìn)行重構(gòu)。
初步的測試代碼如下:
運(yùn)行測試代碼->通過。
在下一篇文章我們將正式開始重構(gòu)。地址:使用重構(gòu)移除丑陋的if else代碼(2)
聲明:本文版權(quán)歸作者所有,如需轉(zhuǎn)載請注明出處。
今天我就使用從實際項目中提煉出來的例子來講解一下如何將這類代碼變得更加面向?qū)ο?- 重構(gòu)成模式并且添加測試代碼,
先來看一個丑陋的類:
package de.jingge.refactoring;
public class SystemManager {
public static final int LOGGEDIN = 0;
public static final int LOGGEDOUT = 1;
public static final int IDLE = 2;
int state;
public void login() {
// call service#login()
updateState(LOGGEDIN);
}
public void logout() {
// call service#logout()
updateState(LOGGEDOUT);
}
public void idle() {
// call some other services
updateState(IDLE);
}
public void updateState(int state) {
if (state == LOGGEDIN) {
// do something after logging in is successful,
// for example: show welcome dialog, open the last edit document, etc.
} else if (state == LOGGEDOUT) {
// do something after logging out is successful,
// for example: free used resource, dispose GUI components, etc.
} else if (state == IDLE) {
// do something after the user is idle,
// for example: save the application state temporarily, lock the application, etc.
} else {
throw new IllegalArgumentException("unknown state");
}
this.state = state;
}
}
public class SystemManager {
public static final int LOGGEDIN = 0;
public static final int LOGGEDOUT = 1;
public static final int IDLE = 2;
int state;
public void login() {
// call service#login()
updateState(LOGGEDIN);
}
public void logout() {
// call service#logout()
updateState(LOGGEDOUT);
}
public void idle() {
// call some other services
updateState(IDLE);
}
public void updateState(int state) {
if (state == LOGGEDIN) {
// do something after logging in is successful,
// for example: show welcome dialog, open the last edit document, etc.
} else if (state == LOGGEDOUT) {
// do something after logging out is successful,
// for example: free used resource, dispose GUI components, etc.
} else if (state == IDLE) {
// do something after the user is idle,
// for example: save the application state temporarily, lock the application, etc.
} else {
throw new IllegalArgumentException("unknown state");
}
this.state = state;
}
}
這里我們展示了一個 SystemManager,它負(fù)責(zé)處理用戶在系統(tǒng)中的狀態(tài):登入(logged in),登出(logged out),以及空閑(idle)。從代碼中可以看到,這個類用了int來定義狀態(tài)并且因此導(dǎo)致了updatteState()方法里面出現(xiàn)大量if else。從目前看來這些if else是無法避免的,應(yīng)為這個類需要針對不同的狀態(tài)作出反應(yīng)。隨著狀態(tài)的增加,if else的數(shù)量也會繼續(xù)增加。這個解決方案顯然很差。
那么怎么樣才能讓這個類更加地面向?qū)ο竽兀?br id="i7km89" />
在處理面向?qū)ο笾埃覀兪紫纫帉懸粋€測試類,這也是處理這類歷史遺留下來代碼所必需做的第一步,只有在測試代碼的保護(hù)下,我們才能放心大膽地進(jìn)行重構(gòu)。
初步的測試代碼如下:
package de.jingge.refactoring;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;
public class SystemManagerTest {
private static SystemManager manager;
@BeforeClass
public static void setUpClass() throws Exception {
manager = new SystemManager();
// add some service mock objects
}
@AfterClass
public static void tearDownClass() throws Exception {
}
@Test
public void login() {
manager.login();
assertEquals(manager.state, SystemManager.LOGGEDIN);
}
@Test
public void logout() {
manager.logout();
assertEquals(manager.state, SystemManager.LOGGEDOUT);
}
@Test
public void idle() {
manager.idle();
assertEquals(manager.state, SystemManager.IDLE);
}
}
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;
public class SystemManagerTest {
private static SystemManager manager;
@BeforeClass
public static void setUpClass() throws Exception {
manager = new SystemManager();
// add some service mock objects
}
@AfterClass
public static void tearDownClass() throws Exception {
}
@Test
public void login() {
manager.login();
assertEquals(manager.state, SystemManager.LOGGEDIN);
}
@Test
public void logout() {
manager.logout();
assertEquals(manager.state, SystemManager.LOGGEDOUT);
}
@Test
public void idle() {
manager.idle();
assertEquals(manager.state, SystemManager.IDLE);
}
}
運(yùn)行測試代碼->通過。
在下一篇文章我們將正式開始重構(gòu)。地址:使用重構(gòu)移除丑陋的if else代碼(2)
聲明:本文版權(quán)歸作者所有,如需轉(zhuǎn)載請注明出處。