1、參數校驗
說明:每次開始編寫一個service,首先要做的就是參數校驗。各種不為NULL、不為空的代碼隨處可見,很不爽。所以我們要找一種方法,來簡化這部分的業(yè)務無關代碼。
1.1. Apache給我們提供了一個工具類可以滿足我們的需求:org.apache.commons.lang3.Validate,提供了各種校驗notBlank、notEmpty、notNull等,可以滿足我們的一般需求。還可以自定義未通過校驗的提示語。
try {
long num = 40;
Validate.exclusiveBetween(1, 10, num, "num參數不在1-10范圍內");
}catch (Exception e){
e.printStackTrace();
}
1.2. Guava的Preconditions也實現了類似的功能。
Preconditions.checkArgument(!(StringUtils.isEmpty(userName)
|| StringUtils.isEmpty(password)), "用戶名或密碼不能為空");
1.3. 實體類約束檢查:Hibernate-validator
BeanValidators.validateWithException(validator, dto);
2、分支判斷
說明:選擇正確的判斷語句會對性能有所提升。所以我們要合理的運用switch case、if else、while、for。
如果分支的條件判斷都是等值判斷,且值的范圍較小,則應該使用switch case而不是if else。因為switch內部維護了一個路由表,不需要像if else那樣挨個判斷。但是如果判斷是范圍,則只能用if else來操作了。
雙層for循環(huán)判斷的情況:把內層for拿出來,轉換成字典。
使用策略模式和多態(tài)去掉if/else、switch
參考1
參考2 利用設計模式替代項目中的if else
注: if else 并不都適合用策略模式替代,只有每個分支足夠復雜,且每個分支用不同方法做同一件事,才需要使用策略模式。
3、編譯階段做檢查
改變編碼方式,在編譯階段做錯誤檢查,而不是等到運行階段。
比如switch,如果參數拼寫錯誤,會走default分支,導致不可預測的結果。但是如果參數改為enum類型,則編譯階段就會發(fā)現該錯誤,及時改正。
4、方法可見性
對共有方法進行判定,是否需要公布。
5、不斷去發(fā)現更新工具類
不應該一直使用項目里一些老舊的工具類,應該不斷的去發(fā)現探索新的好用的工具類,例如Apache Commons、Google Guava或者Joda Date。
6、靜態(tài)導入使用
Eg: import static com.google.common.base.Preconditions.checkNotNull;
好處:減少代碼的書寫量;可讀性高。
缺點:如果濫用,可讀性會很差,代碼中都是方法名,看不到類名,類是極具描述性的表示的。
所以,如果方法具有很好的表述性含義,則建議多用靜態(tài)導入。對于枚舉類,還是建議老老實實的書寫。
7、避免臟數據
寧愿讓程序出錯、停止運行,也不要把一些錯誤的數據插入到數據庫。正式的線上系統(tǒng),數據的準確性是最重要的。操作前,一定要反復的進行數據檢查。
第一步:基本判斷約束(null值等基本判斷)
第二步:實體屬性約束(滿足jsr 303等基礎判斷)
第三步:業(yè)務條件約束(需求提出的不同的業(yè)務約束)
第四步:處理業(yè)務邏輯
Eg: 下面貼出一段用戶發(fā)表文章的示例代碼:
public ResponseEntity addArticle(Integer uid, Article article) {
//參數數據檢驗
// 1.用戶id不能為空,且此用戶存在
Preconditions.checkNotNull(uid);
User user = userDao.findOne(uid);if(null== user){
throw new RuntimeException("找不到當前用戶!");
}
// 2.文章的必要字段不能為空
BeanValidators.validateWithException(validator, article);
// 業(yè)務邏輯代碼
article.setUser(user);
ResponseEntity ret = articleDao.save(article);
return ret;
}
后面會抽時間不定期補充