編碼優(yōu)化性定義分享

一戈毒、代碼的可讀性

1.1艰猬、命名

命名隨處可見,給變量埋市、函數(shù)冠桃、參數(shù)、類和封包命名道宅。應(yīng)遵循規(guī)范文檔的命名規(guī)范食听,并且一旦發(fā)現(xiàn)有更好的名稱,就換掉舊的污茵。這么做樱报,你和讀你代碼的人都會更開心。

1.2泞当、格式
  • 大括號與if, else, for, do, while語句一起使用迹蛤,即使只有一條語句(或是空),也應(yīng)該把大括號寫上 襟士;
  • 空的塊狀結(jié)構(gòu)可以簡寫為一行盗飒,但如果他是多塊狀結(jié)構(gòu)的一部分,無論如何也要換行陋桂;
//空塊狀結(jié)構(gòu)
void do(){}

if() return ;

//多塊狀結(jié)構(gòu)
if(expression){

}else if(otherExpression){ 

}else{

}
  • 一行代碼超過80個字符需要換行逆趣;
  • 一個方法函數(shù)內(nèi)的代碼不超過100行。
1.3章喉、異常
  • 異常處理需要對java和spring的異常體系有所了解汗贫,并遵循對已知捕獲身坐、對未知拋出的原則,進(jìn)行項(xiàng)目內(nèi)異常體系的構(gòu)建落包、優(yōu)化部蛇;
  • 長代碼塊的異常需要分別處理,不要在一個try catch中進(jìn)行捕獲咐蝇;
  • 反例:
public void test(){
        try{
                do smoething
                do smoething
                do smoething
        }catch(Exception e){

        }
}
  • 正例:
public void test(){
        try{
                do smoething
        }catch(Exception e){

        }
        try{
                do smoething
        }catch(Exception e){

        }
        try{
                do smoething
        }catch(Exception e){

        }
}
  • 循環(huán)體內(nèi)不要使用try catch涯鲁,需要時在循環(huán)外使用;
1.4有序、常量/魔術(shù)值
  • 所有常量的修飾符必須含有static final抹腿;
  • 常量的使用域需要限制在相應(yīng)模塊中,防止版本更迭后其他模塊發(fā)生錯誤旭寿;
  • 代碼中涉及邏輯中斷和條件判斷不要出現(xiàn)不明的警绩、未經(jīng)釋義的值,需要有明確命名魔術(shù)值盅称;
  • 反例:
public boolean hasAdminRole(List<Role> roles){
    for(Role role : roles){
        if(user.getId == 9527){
            return true;
        }
    }
    return false;
}
  • 正例:
//key角色對應(yīng)的id
private static final Integer KEY_ROLE_ID = 9527;

public boolean hasKeyRole(List<Role> roles){
    for(Role role : roles){
        if(user.getId == KEY_ROLE_ID){
            return true;
        }
    }
    return false;
}
1.5肩祥、函數(shù)
  • 每一個方法函數(shù)在邏輯上應(yīng)該包含明確的 輸入(參數(shù))和輸出(返回值);
  • 一個方法函數(shù)需要明確的主體邏輯和次要邏輯缩膝,對于復(fù)雜冗長的函數(shù)混狠,盡可能的展現(xiàn)主體邏輯,拆分次要邏輯到其他函數(shù)中疾层,進(jìn)行模塊化編程将饺;
  • 反例:
public LoginUser getUserInfo(){
    //獲取用戶 token
    ServletAttributs requestAttributes = RequestContextHolder.getRequestAttributes();
    HttpServletRequest request = requestAttributes.getRquest();
    String token = request.getHeader("access_token");
    if(StringUtils.isEmpty(token)){
        throw new EmptyLoginTokenException("用戶登錄token獲取錯誤");
    }
    //根據(jù)token 獲取用戶信息
    SysUser user = (SysUser)redisUtil.get(token);
    //轉(zhuǎn)換loginUser
    LoginUser loginUser = new LoginUser();
    loginUser.setId(user.getId());
    loginUser.setAccount(user.getAccout());
    loginUser.setName(user.getName());
    ...
    //補(bǔ)充角色信息
    List<SysRole> roles = new ArrayList<>();
    roles = roleService.getRolesByUserId(loginUser.getId());
    if(CollectionUtils.isNotEmpty(roles)){
            Set<SysRole> roleSet = new HashSet(roles);
        roles.setRoles(roleSet);
         //補(bǔ)充權(quán)限信息
        List<SysPermission> permissions = new ArrayList<>();
        permissions = permissionService.getPermissionsByRoles(roles);
        if(CollectionUtils.isNotEmpty(permissions)){
            Set<SysRSysPermissionole> permissionSet = new HashSet(permissions);
            roles.setPermissions(permissionSet);
            ...
        }
    }
         return loginUser;
}
  • 正例:
public LoginUser getUserInfo(){
    //獲取用戶 token
    String token = getToken();
    //根據(jù)token 獲取用戶信息
    SysUser user = (SysUser)redisUtil.get(token);
    if(ObjectUtil.isNEmpty(user)){
         return null;
    }
    //轉(zhuǎn)換loginUser
    LoginUser loginUser = convertLoginUser(user);
    //補(bǔ)充角色信息
    supplyLoginUser(loginUser);
         return loginUser;
}

private String getToken(){
    ServletAttributs requestAttributes = RequestContextHolder.getRequestAttributes();
    HttpServletRequest request = requestAttributes.getRquest();
    String token = request.getHeader("access_token");
    if(StringUtils.isEmpty(token)){
        throw new EmptyLoginTokenException("用戶登錄token獲取錯誤");
    }
    return token;
}

private LoginUser convertLoginUser(SysUser user){
    LoginUser loginUser = new LoginUser();
    loginUser.setId(user.getId());
    loginUser.setAccount(user.getAccout());
    loginUser.setName(user.getName());
    ...
    return loginUser;    
}

private void supplyLoginUser(LoginUser loginUser){
    List<SysRole> roles = new ArrayList<>();
    roles = roleService.getRolesByUserId(loginUser.getId());
    if(CollectionUtils.isNotEmpty(roles)){
            Set<SysRole> roleSet = new HashSet(roles);
        roles.setRoles(roleSet);
         //補(bǔ)充權(quán)限信息
        List<SysPermission> permissions = new ArrayList<>();
        permissions = permissionService.getPermissionsByRoles(roles);
        if(CollectionUtils.isNotEmpty(permissions)){
            Set<SysRSysPermissionole> permissionSet = new HashSet(permissions);
            roles.setPermissions(permissionSet);
            ...
        }
    }
}
1.6、嵌套
  • 一個方法函數(shù)內(nèi)的嵌套不要超過三層痛黎;
  • 反例:
void render(List<User> users){
    if(CollectinUtils.isNotEmpty(users)){
       for(User user : users){
           if(CollectinUtils.isNotEmpty(user.getRoles())){
              for(Role role : user.getRoles()){
                  do something
              } 
           }
       }
    }
}
  • 正例:
void render(List<User> users){
    if(CollectinUtils.isEmpty(users)){
        return;
    }
    for(User user : users){
      if(CollectinUtils.isEmpty(user.getRoles())){
         continue;
       }
      for(Role role : user.getRoles()){
         do something         
      }   
    }
}
1.7予弧、條件
  • 循環(huán)條件進(jìn)行邏輯上的合并;
  • 合并前:
List goodNames = new ArrayList<>();
if(bool){
    for (String name: names) {
      if (name.contains("bad")) {
        continue;
      }
      goodNames.add(name);
      ...
    } 
}
  • 合并后:
List goodNames = new ArrayList<>();
for (String name: names) {
  if (!name.contains("bad")) {
    goodNames.add(name);
    ...
  }
}  
  • 多條件判斷超過三個需要換行舅逸;
if(menus.contain(MenuEnums.HOME_PAGE)
          && menus.contain(MenuEnums.ERROR_PAGE)
          && menus.contain(MenuEnums.LOGIN_PAGE)){

}
  • 賦值條件為2個時盡量使用三目運(yùn)算符號桌肴;
Subject sub = new Subject();
sub.setDataScope(UserContext.hasAdminRole()?"all":user.getDataScope());
1.8皇筛、邊界

項(xiàng)目管理中琉历,項(xiàng)目由進(jìn)度、成本水醋、質(zhì)量和邊界構(gòu)成旗笔,邊界是指研發(fā)過程中應(yīng)完成需求對應(yīng)的功能,避免不必要的過度編碼拄踪,由此引發(fā)的返工問題也會回過頭來影響進(jìn)度蝇恶、成本與代碼質(zhì)量。

1.9惶桐、注釋
  • 遵循注釋規(guī)范使用單行注釋與多行注釋撮弧,代碼中不要使用尾注釋潘懊;
  • 優(yōu)雅代碼應(yīng)追求即使沒有注釋仍能被看懂的原則,通過規(guī)范的命名和簡介的功能描述減少冗余注釋的編寫贿衍;

二授舟、代碼的可維護(hù)性

  • 編寫時可維護(hù)性:是指在程序或系統(tǒng)上線后爆出 BUG,開發(fā)團(tuán)隊(duì)能夠及時撲滅這個 BUG 且不會爆出其他 BUG贸辈。保持方法的原子性释树,提高代碼內(nèi)聚,能使某處修改的影響降到最低擎淤,這樣某處方法出現(xiàn) BUG奢啥,也不太會影響到其他模塊的正常運(yùn)作;
  • 運(yùn)行時的可維護(hù)性:是指在系統(tǒng)運(yùn)行過程中(或無需再次編碼發(fā)布嘴拢、只需系統(tǒng)重啟一次)修改系統(tǒng)的某項(xiàng)配置并使其生效桩盲,且不影響現(xiàn)在正在進(jìn)行的業(yè)務(wù)和用戶的操作。這要求軟件工程師不能把代碼寫死席吴。例如配置文件正驻、數(shù)據(jù)庫連接字符串、資源文件抢腐、日志等姑曙。

三、代碼的可變更性

  • 提高代碼的復(fù)用:需要對整個系統(tǒng)的整體進(jìn)行分析與合理規(guī)劃迈倍,長期不斷的對系統(tǒng)模型進(jìn)行劃分伤靠,對模型邊界進(jìn)行設(shè)定,保證每個功能被合理地劃分到響應(yīng)的模型的每個類中啼染,這樣可以很好地保證代碼復(fù)用宴合;
  • 設(shè)計(jì)模式:是解決特定問題的一系列套路。它不是語法規(guī)定迹鹅,而是一套用來提高代碼可復(fù)用性卦洽、可維護(hù)性、可讀性斜棚、穩(wěn)健性以及安全性的解決方案阀蒂。

四、技術(shù)評審

技術(shù)評審包含編碼前的方案評審和編碼后的代碼review弟蚀,是代碼質(zhì)量管理方式的一種蚤霞,以下列舉代碼評審階段排排查的典型案例:

  • 功能錯誤
  • 資源泄漏
  • 空的異常處理、缺失日志
  • 事務(wù)的使用
  • 文檔义钉、類昧绣、方法、復(fù)雜算法注釋
  • 重復(fù)代碼
  • 過長的方法參數(shù)列表
  • if/while/for等嵌套3層以上
  • 無實(shí)際意義的類捶闸、方法夜畴、變量名稱
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末拖刃,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子贪绘,更是在濱河造成了極大的恐慌序调,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件兔簇,死亡現(xiàn)場離奇詭異发绢,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)垄琐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進(jìn)店門边酒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人狸窘,你說我怎么就攤上這事墩朦。” “怎么了翻擒?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵氓涣,是天一觀的道長。 經(jīng)常有香客問我陋气,道長劳吠,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任巩趁,我火速辦了婚禮痒玩,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘议慰。我一直安慰自己蠢古,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布别凹。 她就那樣靜靜地躺著草讶,像睡著了一般。 火紅的嫁衣襯著肌膚如雪炉菲。 梳的紋絲不亂的頭發(fā)上堕战,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天,我揣著相機(jī)與錄音颁督,去河邊找鬼践啄。 笑死,一個胖子當(dāng)著我的面吹牛沉御,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播昭灵,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼吠裆,長吁一口氣:“原來是場噩夢啊……” “哼伐谈!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起试疙,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤诵棵,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后祝旷,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體履澳,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年怀跛,在試婚紗的時候發(fā)現(xiàn)自己被綠了距贷。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡吻谋,死狀恐怖忠蝗,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情漓拾,我是刑警寧澤阁最,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站骇两,受9級特大地震影響速种,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜低千,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一哟旗、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧栋操,春花似錦闸餐、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至剔宪,卻和暖如春拂铡,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背葱绒。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工感帅, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人地淀。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓失球,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子实苞,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 1豺撑、編程規(guī)范 本篇規(guī)范基于阿里巴巴、華為的開發(fā)手冊黔牵,在此之上進(jìn)行歸納整理聪轿,歡迎共同改進(jìn)該規(guī)范。 1.1猾浦、命名規(guī)范 ...
    _Rondo閱讀 115評論 0 1
  • 一陆错、命名規(guī)范 1、通用命名規(guī)范 Tips:所有的命名都應(yīng)該遵循3個基本原則金赦,即“清晰性”音瓷、“一致性”、“不要自我指...
    德惟閱讀 268評論 0 0
  • 介紹(Introduction) 本文檔給出了Python代碼的編碼約定素邪,該P(yáng)ython代碼包含主Python發(fā)行...
    優(yōu)雅的步伐閱讀 1,862評論 0 0
  • [寫在開始]代碼質(zhì)量是每個項(xiàng)目都在呼吁的外莲。卻是大家都不愿實(shí)施的。長期效益誘惑抵抗不了短期收益的現(xiàn)實(shí)兔朦。目前偷线,它給予的...
    小趙營閱讀 628評論 1 2
  • 前言 關(guān)于代碼規(guī)范的重要性這里不做過多解釋声邦,能看到這篇文章說明你已經(jīng)開始重視代碼規(guī)范了(代碼規(guī)范看起來是在限制你的...
    iOS鑫閱讀 989評論 1 10