目錄
前言
看到項目代碼中有N多“If-else”,對於一個代碼潔癖患者來說是非常不舒服的,同時我覺得寫出優雅的代碼是可以提升程序猿的工作滿意度。這次我就把我以前的經驗做一個彙總,以備後續參考。
醜陋的代碼
Animal animal = new Animal();
if ("monkey".equals(animalType)){
animal.setFeet(2);
} else if ("pig".equals(animalType)){
animal.setFeet(4);
} else if ("fish".equals(animalType)){
animal.setFeet(1);
}
其實上面這種邏輯可以通過“鍵值對化”來解決。即以if條件作爲key,把設置的值作爲value。當然這種“鍵值對”化可以有很多種辦法:
1、通過spring配置文件
/**
/** 1、把映射關係放到xml文件,然後通過spring加載;
/** 2、找到bean後通過animalType查找animalList對應的value進行設置。
/**
ApplicationContext ac = new FileSystemXmlApplicationContext(new String[]{"D:\\animal.xml"});
List<String, String> animalList = ac.getBean("animal");
Animal animal = new Animal();
animal.setFeet(animalList.get(animalType));
2、通過自定義枚舉類
//* 首先定義一個枚舉類,還是拿上面的醜陋代碼做例子。
public enum AnimalFeetEnum {
FISH("FISH",1),MONKEY("MONKEY",2),PIG("PIG",4);
private String animal;
private int index;
public int getIndex() {
return index;
}
public String getAnimal() {
return feet;
}
private AnimalFeetEnum(String animal, int index){
this.index = index;
this.animal = animal;
}
AnimalFeetEnum getAnimalFeet(String animal) {
for (AnimalFeetEnum temp : AnimalFeetEnum.values()) {
if (animal.equals(temp.getAnimal())) {
return temp;
}
}
return null;
}
}
//* 設置動物的腳
Animal animal = new Animal("FISH");
animal.setFeet(AnimalFeetEnum.getAnimalFeet("FISH")); //* <-當然這裏的“FISH”是表明是一個動態值,具體怎麼傳入看具體的上下文;
3、通過Optional類
有部分的if-else是來自於非空判斷,以前我們的做法一般也是很low但也很無奈(無非寫個StringUtils,然後通過isNull進行層層嵌套判斷)。因爲在JAVA8中引進了Optional,這樣我們就可以直接通過Optional來解決。
//* 以前苦逼的生活是這樣的:
private void printCardNum(User user){
String cardNum = user.getCardNum();
if (cardNum == null){
return;
}
System.out.println(cardNum);
}
//* 當有了Opional,原來生活可以是這麼美好的
private void printCardNum(User user){
Optional<String> options = Optional.ofNullable(user.getCardNum());
options.isPresent(opt -> {
System.out.println(opt);
});
4、通過Map
這個相對簡單,就是通過Map存儲鍵值對,然後通過key獲取value。不過,要保證以下方法取值正確是有前提的。相信各位老司機對HashMap也不陌生,HashMap是通過key的hash值作爲地址進行鏈式存儲的,如果hash值衝突的話最新值會覆蓋舊有值。小心放完進去拿不出來,最穩妥的方式要不是重寫hash()和equals();
public Consts{
//* 初始化動物腳的表
public static final HashMap animalMap = new HashMap();
animalMap.put("FISH",1);
animalMap.put("MONKEY",2);
animalMap.put("PIG",4);
....
}
//* 設置動物對象的“腳”屬性
public Animal(){
@Autowired
private name;
@Autowired
private feet;
public void animal(String name){
this.name = name;
}
//* 從main方法看,通過Animal類的name屬性作爲key去animalMap獲取相應的value
public static void main(String[] args){
Animal animal = new Animal("MONKEY");
animal.setFeet(Consts.animalMap.get(animal.getName()));
}
}
5、策略+工廠模式
首先,針對不同動物實現不同動物腳的邏輯,然後通過策略工廠的方法針對傳入的動物類型實現動態綁定,這樣更能體現JAVA作爲OO的一種語言更加優美的處理,比純粹的使用if-else這種類過程式語言優雅得多。
//* 設置動物接口
public interface IAnimal{
void setFeet();
}
//* 實現這幾種動物
public class Monkey implements IAnimal{
public void setFeet(){
this.feet = 2;
}
}
public class PIG implements IAnimal{
public void setFeet(){
this.feet = 4;
}
}
public class FISH implements IAnimal{
public void setFeet(){
this.feet = 1;
}
}
//* 定義工廠類
public class AnimalFactory{
public static final HashMap<String, int> map = new HashMap<String, int>();
static{
map.put("FISH", FISH);
map.put("MONKEY", MONKEY);
map.put("PIG", PIG);
}
public IAnimal getAnimal(String type){
return map.get(type);
}
//* 通過main方法演示
public static void main(String[] args){
String type = "PIG";
IAnimal animal = AnimalFactory.getAnimal(type);
animal.setFeet();
}
}
結語
實際上,基友的智慧是強大的,消滅if-else也有各種各樣的巧妙且優雅的方法。我的原則是,如果你只是通過不斷的if-else去堆砌你的業務代碼,然後你天天在說沒有技術的提升,那別怪別人,因爲真正的提升是需要靠自己去寫代碼的過程中去發現。這種的代碼能力纔是真正的內功,那些所謂的蝦米蝦米框架的就是一堆招式,招式會變的會過時的,等到雲計算像spring一樣滲透到方方面面的時候那些招式就一點用都沒有,唯有內功纔是可以恆久不變的。
*** 後面想到的或者在網上看到的比較有優雅的也繼續收錄在這裏供自己賞讀。