當長if-else或是switch出現在方法內時通常代表該方法做了一件以上的事。
為了保持方法簡短和清晰度,適當的情況下,我們應該盡量避免長if-else或switch的出現。
如果switch或是if-else的判斷條件(參數)是可以掌控的,那麼可以使用 Replace Parameter with explicit methods 來消除 switch 或是 if-else,
toggleUI方法相當簡單,根據state的值判斷進入哪個條件。e.g.,
private void toggleUI(UIState state, int labelTextId) { if (state == UIState.LOAD_PANEL) { progressBar.setVisibility(View.VISIBLE); languageSpinner.setVisibility(View.GONE); } else if (state == UIState.LANGUAGE_FOUND) { progressBar.setVisibility(View.GONE); languageSpinner.setVisibility(View.VISIBLE); } label.setText(labelTextId); }
觀察所有toggleUI的呼叫點會發現每個呼叫點傳入的參數都是可以控制的。e.g.,
private void setUI() { ... toggleUI(UIState.LOAD_PANEL, R.string.label_loading); } void onReadyPanelDialog(AlertDialog dialog) { ... toggleUI(UIState.LANGUAGE_FOUND, R.string.label_language); ... }
因此我們就能夠把 toggleUI 拆開,分為2個方法 ,e.g.,
private void toggleUIForLoadPanel(int labelTextId){ progressBar.setVisibility(View.VISIBLE); languageSpinner.setVisibility(View.GONE); label.setText(labelTextId); } private void toggleUIForLanguageFound(int labelTextId){ progressBar.setVisibility(View.GONE); languageSpinner.setVisibility(View.VISIBLE); label.setText(labelTextId); }
建立toggleUIForLoadPanel,toggleUIForLanguageFound 後取代的原本 toggleUI 呼叫點,
private void setUI() { ... toggleUIForLoadPanel(R.string.label_loading); } void onReadyPanelDialog(AlertDialog dialog) { ... toggleUIForLanguageFound(R.string.label_language); ... }
再觀察 toggleUIForLoadPanel 和 toggleUIForLanguageFound 的唯一參數(int labelTextId)
發現該參數傳入的數值會跟著方法一致,
toggleUIForLoadPanel 傳入的是 R.string.label_loading
toggleUIForLanguageFound 傳入的是 R.string.label_language
因此可把參數直接刪除,在方法中直接指定即可,e.g.,
private void toggleUIForLoadPanel(){ progressBar.setVisibility(View.VISIBLE); languageSpinner.setVisibility(View.GONE); label.setText(R.string.label_loading); } private void toggleUIForLanguageFound(){ progressBar.setVisibility(View.GONE); languageSpinner.setVisibility(View.VISIBLE); label.setText(R.string.label_language); }
最後刪除掉 toggleUI 方法。
把原本需要2個參數的toggleUI方法重構為2個不需要參數的方法,也讓方法的命名轉為更容易了解( toggleUIForLanguageFound , toggleUIForLOadPanel )
在重構結束後還會發現一些額外的驚喜,原本的 toggleUI 使用 UIState 列舉,而該列舉只使用在 toggleUI 內,隨著 toggleUI 被刪除,UIState 也不需要使用了。