Java-Annotation的一種用法(消除程式碼中冗餘的if/else或switch語句)
阿新 • • 發佈:2020-11-21
# Java-Annotation的一種用法(消除程式碼中冗餘的if/else或switch語句)
### 1.冗餘的if/else或switch
有沒有朋友寫過以下的程式碼結構,大量的if/esle判斷,來選擇不同的執行方式
```java
if(type==1001){
return decodeMsg1001(msg);
}else if(type==1002){
return decodeMsg1002(msg);
}
.....
```
或者上面的程式碼也是可以轉換成相應的switch語句來執行,結構如下所示:
```java
switch(type){
case 1001:{
return decodeMsg1001(msg)
}
case 1002:{
return decodeMsg1002(msg);
}
....
}
```
總之,如果type的值很多的話,就會導致這段程式碼特別的長。如果想在處理訊息的函式中新增一些其他的資訊,則會導致處理訊息的函式體也會比較長。
**Java語言是面向物件的,有沒有一種方法用面向物件的方式來解決這個問題。將大量的if/else語句轉換成使用介面的方式來解決**。答案是有的
### 2.思路想法
上述的問題大多數產生在,多個不同型別的訊息對應著不同的處理方法(不同訊息所對應的資料不一致)。
可以將不同的型別與型別所對應的處理方法,做成一個對映表。即一種type對應於一個typeProcessor,在java中這種資料結構是Map。所以在系統初始化時,先生成這樣一種Map的對應關係。當一種型別type的訊息到來時,從這個map中查找出所對應的處理類,然後動態產生一個介面物件,然後執行介面中的方法。那這樣就會有相應的問題:
- 問題一:每一種型別對應一個處理類,就會有好多實體類,怎麼做好一個型別對應一個處理類
- 問題二:如果一個一個類實體物件的手動新增,也會產生好多冗餘的程式碼。
### 3.訊息對應實現
#### 3.1 利用annotation實現型別與處理類對應
在java中可以利用Annotation這一特性,來實現訊息型別與實體類的對應,先建立一個annotation。
```java
@Target(ElementType.TYPE) //TYPE(型別)是指可以用在Class,Interface,Enum和Annotation型別上.
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ProtocolCommand {
int msgCommand() default 0 ;
}
```
建立好相應的Annotation後,可以新增在每一個訊息處理類上,在Annotation中有一個屬性為msgCommand,是int型別的,這樣就可以做到對應。
#### 3.2訊息處理介面
為方便操作,可以建立一個訊息處理介面,對應每一種型別的訊息處理類都需要實現這一介面,這樣的好處在動態產生物件很好的做到統一處理。
```java
public interface IUbloxMsg {
public int decodeUbxMsg(RawData rawData);
}
```
這裡的介面很簡單,如果想處理複雜的業務,可以自行在介面中新增相應的方法。
**這裡也可以不用介面這一特性來實現功能,也可以用抽象類 來實現。每一種特性都可以實現功能。**
#### 3.3具體訊息實現
```java
@ProtocolCommand(msgCommand=UbloxConstant.ID_NAVSOL)
public class NavSolUbloxMsgImpl implements IUbloxMsg {
public int decodeUbxMsg(RawData rawData) {
return 0;
}
}
```
可以看到在具體的訊息型別處理類上,加上我們自定義的註解,即可實現具體訊息型別與具體訊息處理類對應。
### 4.生成Map訊息型別對映
#### 4.1訊息處理類掃描,得到Class集合
通常情況下,為了方便管理訊息處理類應該放在一個包目錄下。所以我們需要自動掃描出這個包目錄下的所有的class,產生Class集合。然後在這個集合中查詢到有我們自定義註解的類,同時得到註解物件,獲取訊息型別,並將此訊息型別新增至Map訊息對映中。
類掃描程式碼核心部分程式碼如下:
```java
public static ClassFilter cFilter = new ClassFilter(true);
//傳入的引數為包名
public st