java else if和switch_如何优雅地优化代码中的的if else和switch
引言
一般來說,隨著我們項目的迭代以及業務的越來越復雜,項目中的分支判斷會原來越多。當項目中涉及到復雜的業務判斷或者分支邏輯時,我們就需要考慮是否需要對項目進行重構了,或者if else和switch case是否能夠滿足當前項目的復雜度。
我們舉一個簡單的例子,假如我們是馬戲團的老板,在訓練一些動物去做一些指令,剛開始很簡單,只訓練了一條狗,當狗握了一下手后,給她獎勵一些狗糧。這樣慢慢地小狗就學會了握手。
我們先定義一條小狗對象,小狗做了某些事情(“握手”)后,可以得到一些獎勵
public class Dog {
public void train(){
System.out.println("握手");
}
public void getReward(){
System.out.println("狗糧");
}
}
定義馴獸師,通過train來訓練動物
public class Beast {
/**
* 訓練
*/
public void train(Dog dog){
/**
* 狗狗做了一些事情
*/
dog.train();
/**
* 狗狗得到獎勵
*/
dog.getReward();
}
}
如果我們只需要訓練一條動物,那么相對來說比較簡單。但是后來馬戲團又引進了一頭獅子,需要訓練獅子鉆火圈,因此,為了區分狗和獅子,我們增加了一種類型區分訓練的動物是狗還是獅子。
public class Lion {
public void train(){
System.out.println("鉆火圈");
}
public void getReward(){
System.out.println("得到一只雞");
}
}
重新修改Beast類,使其既可以訓練小狗,又可以訓練獅子
public class Beast {
public void train(Object animal, int type){
if (type == 1){
trainDog((Dog)animal);
}else if (type == 2){
trainLion((Lion)animal);
}
}
/**
* 訓練
*/
public void trainDog(Dog dog){
/**
* 狗狗做了一些事情
*/
dog.train();
/**
* 狗狗得到獎勵
*/
dog.getReward();
}
/**
* 訓練
*/
public void trainLion(Lion lion){
/**
* 狗狗做了一些事情
*/
lion.train();
/**
* 狗狗得到獎勵
*/
lion.getReward();
}
}
我們通過type類型來區分訓練的動物類型,后來馬戲團引來了越來越多的動物,那我們的type的取值會越來越多:1表示狗,2表示獅子,3表示貓,4表示老虎,5表示猴子...等等。而且隨著系統越來越復雜,我們在訓練之前不同的動物還需要做不同的準備工作。當然,目前的系統只要增加if else或者switch case是可以滿足需求的,但這樣寫顯得不是太優雅,我們希望找到一種比較優雅比較有設計感的方式來取代if else或者switch case
優化if else
在做優化之前,我們需要先弄清楚我們的目的。我們是馬戲團的馴獸師,目的是訓練動物。
目的:訓練動物做一些事情(doSomething)
方式:通過獎勵(getReward)誘導動物進行訓練。
有了上面的目的之后,我們就可以定義一個模型animal
public interface IAnimal {
/**
* 獲取動物種類
* @return
*/
int getType();
/**
* 訓練動作
*/
void train();
}
Animal只暴露兩個方法,其中doSomething是專門用來訓練動物的,至于如何訓練全都由子類實現。
getType():用來區分不同的動物
train():訓練動物
然后我們定義一個子類實現這個接口,用來具體化如何訓練動物
public abstract class AbsTrainAnimal implements IAnimal{
/**
* 訓練前需要做的準備
*/
abstract void beforeTrain();
/**
* 訓練后需要做的準備
*/
abstract void afterTrain();
/**
* 訓練出現異常需要做的
*/
abstract void exceptionTrain(Throwable throwable);
/**
* 具體訓練
*/
abstract void doSomething();
/**
* 訓練動作
*/
@Override
public final void train() {
try {
beforeTrain();
doSomething();
afterTrain();
}catch (Throwable throwable){
exceptionTrain(throwable);
}
}
}
我們定義了一個抽象類用來實現IAnimal接口,作為所有動物訓練的基類。其中實現的接口train使用了final進行了限制,防止子類對其進行覆蓋操作。
在AbsTrainAnimal中,我們對train()進行了各種功能的細化
doSomething:具體訓練的內容
beforeTrain:訓練之前需要做的一些準備
afterTrain:訓練之后需要做的事情
exceptionTrain:訓練中發生意外應該如何處理
因為所有動物的以上四個方法可能都不相同,所以我們聲明為abstract方法,方便子類自己實現。基于以上設計,我們就可以定義一個Dog類,對其進行訓練。
public class Dog extends AbsTrainAnimal {
/**
* 訓練前需要做的準備
*/
@Override
void beforeTrain() {
System.out.println("撫摸額頭以示鼓勵");
}
/**
* 訓練后需要做的準備
*/
@Override
void afterTrain() {
System.out.println("獎勵一些狗糧");
}
/**
* 訓練出現異常需要做的
*
* @param throwable
*/
@Override
void exceptionTrain(Throwable throwable) {
System.out.println("出去罰站");
}
/**
* 具體訓練
*/
@Override
void doSomething() {
System.out.println("握手");
}
/**
* 獲取動物種類
*
* @return
*/
@Override
public int getType() {
return 1;
}
}
同時定義一個獅子Lion
public class Lion extends AbsTrainAnimal {
/**
* 訓練前需要做的準備
*/
@Override
void beforeTrain() {
System.out.println("友好交流");
}
/**
* 訓練后需要做的準備
*/
@Override
void afterTrain() {
System.out.println("獎勵一只雞");
}
/**
* 訓練出現異常需要做的
*
* @param throwable
*/
@Override
void exceptionTrain(Throwable throwable) {
System.out.println("緊急送往醫院");
}
/**
* 具體訓練
*/
@Override
void doSomething() {
System.out.println("鉆火圈");
}
/**
* 獲取動物種類
*
* @return
*/
@Override
public int getType() {
return 2;
}
}
我們可以看到,Dog和Lion的動物種類是不一樣的,Dog為1,Lion為2。我們可以根據type區分是獅子還是狗。但為了避免使用if else進行區分,我們需要一個工廠類來生產這兩種動物。
@Service
public class AnimalFactory {
private static List> animalLists = Lists.newArrayList();
private static Map animalMaps = Maps.newHashMap();
static {
animalLists.add(Dog.class);
animalLists.add(Lion.class);
}
@PostConstruct
public void init() throws IllegalAccessException, InstantiationException {
for (Class extends IAnimal> clazz : animalLists){
Object obj = clazz.newInstance();
animalMaps.put(obj.getType(), obj);
}
}
/**
* 構建動物類
* @param type
* @return
*/
IAnimal build(int type){
return animalMaps.get(type);
}
}
我們有了這個工廠類,就可以根據不同的動物類型獲取不同的對象,并對其進行訓練。當然我們這里都是使用的單例模式,每個對象只對應一個實例,如果每次都生成不同的實例,可以對其進行簡單的改造即可實現。
我們再重寫馴獸師Beast類
@Service
public class Beast {
@Resource
private AnimalFactory animalFactory;
/**
* 訓練動物,只需要知道動物的類型即可
* @param type
*/
public void train(int type){
IAnimal animal = animalFactory.build(type);
animal.train();
}
}
可以看到train方法只需要關系動物類型即可,不需要再根據type進行判斷動物類型在對其進行不同的操作。如果有新的動物加入,只需要實現AbsTrainAnimal基類,然后向AnimalFactory進行注冊即可。避免了根據不同type進行if else或者switch的判斷
總結
其實,上述所述的方法不但但省去了if else的判斷,也是目前比較流行的領域模型的一種實現方式。IAnimal是領域內對外暴露的唯一方式,外部領域(馴獸師)不需要關心任何內部實現的細節。內部的實現完全集合在IAnimal內。
總結
以上是生活随笔為你收集整理的java else if和switch_如何优雅地优化代码中的的if else和switch的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java bundle_java.uti
- 下一篇: java flash截图_求大神们帮助,