開發規約的意義與細則

語言: CN / TW / HK

眾所周知,制訂交通法規表面上是要限制行車權,實際上是保障公眾的人身安全。試想如果沒有限速,沒有紅綠燈,沒有靠右行駛條款,誰還敢上路。消防局最主要的工作不是滅火,而是為了不發生火災建立很多規範。如果發生火災,說明前面的工作沒有做到位。同理,對軟體來說,開發規約絕不是消滅程式碼內容的創造性、優雅性,而是限制過度個性化,推行相對標準化,以一種普遍認可的方式一起做事。

綜上所述,開發規約的目標:

  1. 碼出高效:標準統一,提升溝通效率和研發效能。

  2. 碼出質量:防患未然,提升質量意識和系統可維護性,降低故障率。

  3. 碼出情懷:工匠精神,追求極致的卓越精神,打磨精品程式碼。

開發規約從無到有,只是短期的目標;使大家遵守開發規約的成本極大降低,釋出上線的應用符合開發規約是中期目標;而遠期目標是從有到無,因為人人自覺遵守,規約和諧地融入程式碼的字裡行間,規約似乎消失了,但又無處不在。

最近,結合新品技術團隊的現狀,分析了系統架構背後的問題,並制定了一系列團隊開發規約,可以從以下三方面展開。

大綱

  1. 開發規約之道

  2. 開發規約之術

  3. 開發規約執行方法論

開發規約之道

  1. 程式碼 規範不應該被定為 KPI

大部分團隊應該都是有KPI的,而且一般重要的事情都會被定成 KPI,所以有些團隊為了強調程式碼規範,將其定為某些員工的KPI,但是這並不能達成好的效果,因為程式碼 規範不應該是 一個 文件, 程式碼 規範應該是一種行為,一種持續的行為 ,而 KPI是要求可以量化有明確目標的。若把程式碼規範當KPI,背了KPI的員工為了讓KPI可量化,通常情況會寫出來一個程式碼規範文件,眾所周知文件最可量化的當然是頁數,故最終可能會產出一個幾十頁的程式碼規範,幾乎面面俱到,看起來很高大上。但是要求大家按照文件落地就很難,讓大家理解認可執行它,並且還需要有相應的監督機制、審查機制來保證大家確實按規範在寫程式碼。結合當前團隊現狀考慮,後者是整個程式碼規範實施的難點,因為大部分人會贊同:一個被 100% 徹底執行了的 40 分程式碼規範應該是好於一個被執行了 40%的100分程式碼規範。

  1. 制定程式碼規範要循序漸進

程式碼規約的實施不是一蹴而就的,是一個過程,需要團隊能夠在編寫程式碼過程完全做到規範是需要時間的,所以初期技術有必要在評估專案開發週期中做好時間buffer,後期慢慢形成一種行為意識時,便是做到從無到有的狀態。通常情況新專案需求節奏都會非常快,基礎框架、基礎元件、大批量業務需求要開發,又因為是新專案,通常不會有特別多的人力投入,這種情況下,一個很嚴格冗長的程式碼規範,要求大家在拼命跑的過程中還要去理解執行你的規範,可能性大嗎?所以這個時期的程式碼規範需要非常簡單易於理解,要在所有人即使在趕需求,也能忍受的範圍內制定規範。這個階段最急迫的需求是用簡單的程式碼規範讓大家養成習慣,提升意識,宣告這個專案是有規範的。

  1. 制定程式碼規範要獨裁

上面一段提到程式碼規範應該循序漸進,之前看到過的一種做法是:團隊內大家一起討論,民主決定某一些規範的細節,因為這樣可以出來一個適配這個團隊的程式碼規範。

這聽起來很美好,非常民主,但是這麼做的結果是什麼?我猜應該會有很多人又回憶起“大括號應不應該換行”、“else 是否應該換行”、“是否允許空兩行”、“JS 結尾帶不帶分號”等類似的爭論,然而這些爭論是有必要的嗎?說白了,大部分爭論找的理由都只是在為自己的程式碼習慣爭取更多空間。這樣的爭論還只是“民主”引發問題的開始,更嚴重的是這會在所有開發人員心中形成一種“規範是可以商量和討論的”心理暗示,這必對後續規範的執行成為阻礙,特別是一些本身就有爭議的點。

正因為上述原因,制定規範時需要“獨裁”。我們的目標很清晰,就是要求程式碼寫法一致,“獨裁”的基礎上可以選擇一個第三方的標準,例如細的條目可以完全選擇集團內部的標準。首先可以保證的是這些規範都是有理有據;其次,“獨裁”使用的規範來源於權威的標準體系,對團隊內所有人公平;最後,這樣的規範和行業更親近。

開發規約之術

   設計規約

  • 傳統分層架構

傳統分層架構通過Controller,Service,Manager, DAO層來組織業務邏輯,通過 貧血模型 來傳遞上下文資料,所有的業務邏輯不需要考慮怎麼組織,統統往Manager和Service中寫。如果遇到更加複雜的邏輯,那就加一些設計模式來處理(本質還是封裝Service和Manager)。這種方式屬於面向過程開發的 事務指令碼 模式,該方式在一些比較簡單的CRUD場景下比較適用,但當邏輯越來越複雜的時候Manager和Service會越來越膨脹和難以維護。

舉個例子 ,我們使用ServiceItemService(服務項相關服務)來處理服務項相關的邏輯,我們需要維護以下層次:

  1. 儲存邏輯;

  2. 資料轉換;

  3. 依賴中介軟體;

  4. 各種業務邏輯;

你會發現一個service承擔了太多職責,即要與中介軟體打交道,又要了解儲存細節,還要承擔各式各樣的業務邏輯。當業務邏輯越來越複雜,未來service和manager會變得越來越難以維護。<阿里巴巴Java開發手冊>中使用的架構,很難解決以上耦合的問題。

  • 六邊形架構

傳統分層的問題核心就在於耦合,而面對複雜的業務系統,我們要做的事情就是 解耦

六邊形架構將整體的軟體系統一分為二,六邊形之外是系統的依賴,六邊形之內是系統內部需要實現的業務系統,六邊形外部是我們與外部系統使用者的互動,左邊是我們的下游,右邊是上游依賴。內外部通過介面卡來進行互動和解耦。

六邊形架構落地時與傳統的分層模型很類似,但是更加明確了不同分層的職責和邊界。

  • 程式碼層次

  1. Client層:對外的介面,DTO,Enum等等,是最輕量的包,所有層都可以依賴client,client不應該依賴任何其他層;

  2. Adaptor層:負責對外系統的適配,Controller,HSF,MTOP介面實現都屬於這一層;

  3. Application層:Application按照業務場景進行組織,主要負責互動引數的處理(入參校驗,出參錯誤資訊轉換),領域邏輯的組織編排;

  4. Domain層 :封裝了核心的業務邏輯,通過領域服務DomainService和領域物件DomainEntity對外提供業務實體物件和計算邏輯。

  5. Infrastructure層:負責外部依賴引入,資料庫,外部hsf依賴,cache,mq等等。同時也是領域層與外部系統的防腐層(Anti-Corruption-Layer)。

  • 新老分層對比

兩者其實非常相似,核心區別在於業務邏輯層新增了領域和應用層,進行了更細化的職責劃分。

   異常處理

  1. Java 類庫中定義的可以通過預檢查方式規避的RuntimeException異常不應該通過catch 的方式來處理,比如:NullPointerException,IndexOutOfBoundsException等等。說明:無法通過預檢查的異常除外,比如,在解析字串形式的數字時,可能數字格式錯誤,不得不通過catch NumberFormatException來實現。正例:if (obj != null) {...}反例:try { obj.method() } catch (NullPointerException e) {…}

  2. 異常捕獲後不要用來做流程控制,條件控制。說明:異常設計的初衷是解決程式執行中的各種意外情況,且異常的處理效率比條件判斷方式要低很多。

  3. catch時請分清穩定程式碼和非穩定程式碼,穩定程式碼指的是無論如何不會出錯的程式碼。對於非穩定程式碼的catch儘可能進行區分異常型別,再做對應的異常處理。說明:對大段程式碼進行try-catch,使程式無法根據不同的異常做出正確的應激反應,也不利於定位問題,這是一種不負責任的表現。正例:使用者註冊的場景中,如果使用者輸入非法字元,或使用者名稱稱已存在,或輸入密碼過於簡單,在程式上作出分門別類的判斷,並提示給使用者。

  4. 捕獲異常是為了處理它,不要捕獲了卻什麼都不處理而拋棄之,如果不想處理它,請將該異常拋給它的呼叫者。最外層的業務使用者,必須處理異常,將其轉化為使用者可以理解的內容。

  5. 事務場景中,丟擲異常被catch後,如果需要回滾,一定要手動回滾事務。

  6. finally塊必須對資源物件、流物件進行關閉,有異常也要做try-catch。說明:如果JDK7,可以使用try-with-resources方式。

  7. 不要在finally塊中使用return。說明:try塊中的return語句執行成功後,並不馬上返回,而是繼續執行finally塊中的語句,如果此處存在return語句,則在此直接返回,無情丟棄掉try塊中的返回點。

    反例:

    private int x = 0;
    public int checkReturn() {
    try {
    // x等於1,此處不返回
    return ++x;
    } finally {
    // 返回的結果是2
    return ++x;
    }
    }
  8. 捕獲異常與拋異常,必須是完全匹配,或者捕獲異常是拋異常的父類。說明:如果預期對方拋的是繡球,實際接到的是鉛球,就會產生意外情況。

  9. 方法的返回值可以為null,不強制返回空集合,或者空物件等,必須添加註釋充分說明什麼情況下會返回null值。說明:本規約明確防止NPE是呼叫者的責任。即使被呼叫方法返回空集合或者空物件,對呼叫者來說,也並非高枕無憂,必須考慮到遠端呼叫失敗,執行時異常等場景返回null的情況。

  1. 防止NPE,是程式設計師的基本修養,注意NPE產生的場景:

     1) 返回型別為基本資料型別,return包裝資料型別的物件時,自動拆箱有可能產生NPE。  反例:public int f(){ return Integer物件},如果為null,自動解箱拋NPE。 2) 資料庫的查詢結果可能為null。 3) 集合裡的元素即使isNotEmpty,取出的資料元素也可能為null。 4) 遠端呼叫返回物件時,一律要求空指標判斷,防止NPE。 5) 對於session中獲取的資料,建議進行NPE檢查,避免空指標。 6) 級聯呼叫obj.getA().getB().getC();易產生NPE。

   日誌規約

  1. 應用中不可直接使用日誌系統(Log4j、Logback)中的API,而應依賴使用日誌框架(SLF4J、JCL--Jakarta Commons Logging)中的API。什麼是日誌框架和日誌系統,請參考webx作者寶寶的文章,文章裡也詳細說明了為什麼不能直接依賴使用日誌系統而是日誌框架,以及應用的pom中如何做dependencyManagement。說明:日誌框架(SLF4J、JCL--Jakarta Commons Logging)的使用方式(推薦使用SLF4J):使用SLF4J:

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    private static final Logger logger = LoggerFactory.getLogger(Test.class);
  2. 在日誌輸出時,字串變數之間的拼接使用佔位符的方式。說明:因為String字串的拼接會使用StringBuilder的append()方式,有一定的效能損耗。使用佔位符僅是替換動作,可以有效提升效能。正例:

  3. logger.debug("Processing trade with id: {} and symbol: {}", id, symbol);
  4. 生產環境禁止直接使用System.out 或System.err 輸出日誌或使用e.printStackTrace()列印異常堆疊。說明:標準日誌輸出與標準錯誤輸出檔案每次Jboss重啟時才滾動,如果大量輸出送往這兩個檔案,容易造成檔案大小超過作業系統大小限制。

  5. 異常資訊應該包括兩類資訊:案發現場資訊和異常堆疊資訊。如果不處理,那麼往上拋。正例:logger.error("inputParams:{} and errorMessage:{}", 各類引數或者物件toString(), e.getMessage(), e);

  6. 日誌列印時禁止直接用JSON工具將物件轉換成String。說明:如果物件裡某些get方法被覆寫,存在丟擲異常的情況,則可能會因為列印日誌而影響正常業務流程的執行。正例:列印日誌時僅打印出業務相關屬性值或者呼叫其物件的toString()方法。

  7. 謹慎地記錄日誌。生產環境禁止輸出debug日誌;有選擇地輸出info日誌;如果使用warn來記錄剛上線時的業務行為資訊,一定要注意日誌輸出量的問題,避免把伺服器磁碟撐爆,並記得及時刪除這些觀察日誌。說明:大量地輸出無效日誌,不利於系統性能提升,也不利於快速定位錯誤點。記錄日誌時請思考:這些日誌真的有人看嗎?看到這條日誌你能做什麼?能不能給問題排查帶來好處?

   日誌規約

  • 建表規約

  1. 表達是與否概念的欄位,必須使用is_xxx的方式命名,資料型別是unsigned tinyint(1表示是,0表示否),此規則同樣適用於odps建表。說明:任何欄位如果為非負數,必須是unsigned。注意:POJO類中的任何布林型別的變數,都不要加is字首,所以,需要在<resultMap>設定從is_xxx到xxx的對映關係。資料庫表示是與否的值,使用tinyint型別,堅持is_xxx的命名方式是為了明確其取值含義與取值範圍。正例:表達邏輯刪除的欄位名is_deleted,1表示刪除,0表示未刪除。

  2. 表名、欄位名必須使用小寫字母或數字,欄位命名可參考附2;禁止出現數字開頭,禁止兩個下劃線中間只出現數字。資料庫欄位名的修改代價很大,因為無法進行預釋出,所以欄位名稱需要慎重考慮。說明:MySQL在Windows下不區分大小寫,但在Linux下預設是區分大小寫。因此,資料庫名、表名、欄位名,都不允許出現任何大寫字母,避免節外生枝。正例:getter_admin,task_config,level3_name反例:GetterAdmin,taskConfig,level_3_name

  1. 表名不使用複數名詞。說明:表名應該僅僅表示表裡面的實體內容,不應該表示實體數量,對應於DO類名也是單數形式,符合表達習慣。

  2. 保留字,如desc、range、match、delayed等,參考官方保留字

  1. 唯一索引名為uk_欄位名;普通索引名則為idx_欄位名。說明:uk_ 即 unique key;idx_ 即index的簡稱。

  2. 小數型別為decimal,禁止使用float和double。說明:在儲存的時候,float 和 double 都存在精度損失的問題,很可能在比較值的時候,得到不正確的結果。如果儲存的資料範圍超過 decimal 的範圍,建議將資料拆成整數和小數並分開儲存。

  1. 如果儲存的字串長度幾乎相等,使用CHAR定長字串型別。

  2. varchar是可變長字串,不預先分配儲存空間,長度不要超過5000,如果儲存長度大於此值,定義欄位型別為TEXT,獨立出來一張表,用主鍵來對應,避免影響其它欄位索引效率。

  1. 表必備三欄位:id, gmt_create, gmt_modified。說明:其中id必為主鍵,型別為bigint unsigned、單表時自增、步長為1;分表時改為從TDDL Sequence取值,確保分表之間的全域性唯一。gmt_create, gmt_modified的型別均為date_time型別,前者現在時表示主動式建立,後者過去分詞表示被動式更新。

  2. 表的命名最好是遵循“業務名稱_表的作用”,避免上雲梯後,再與其它業務表關聯時有混淆。正例:tiger_task / tiger_reader / force_codereview

  1. 庫名與應用名稱儘量一致。

  2. 如果修改欄位含義或對欄位表示的狀態追加時,需要及時更新欄位註釋。

  • SQL規約

  1. 不要使用count(列名)或count(常量)來替代count(*),count(*)就是SQL92定義的標準統計行數的語法,跟資料庫無關,跟NULL和非NULL無關。說明:count(*)會統計值為NULL的行,而count(列名)不會統計此列為NULL值的行。

  2. count(distinct col) 計算該列除NULL之外的不重複數量。注意 count(distinct col1, col2) 如果其中一列全為NULL,那麼即使另一列有不同的值,也返回為0。

  1. 當某一列的值全是NULL時,count(col)的返回結果為0,但sum(col)的返回結果為NULL,因此使用sum()時需注意NPE問題。正例:可以使用如下方式來避免sum的NPE問題:SELECT IFNULL(SUM(column), 0) FROM table;

  2. 對於資料庫中表記錄的查詢和變更,只要涉及多個表,都需要在列名前加表的別名(或表名)進行限定。說明:對多表進行查詢記錄、更新記錄、刪除記錄時,如果對操作列沒有限定表的別名(或表名),並且操作列在多個表中存在時,就會拋異常。正例:select t1.name from table_first as t1 , table_second as t2 where t1.id=t2.id;反例:在飛豬某業務中,由於多表關聯查詢語句沒有加表的別名(或表名)的限制,正常執行兩年後,最近在某個表中增加一個同名欄位,在預釋出環境做資料庫變更後,線上查詢語句出現出1052異常:Column 'name' in field list is ambiguous,導致票務交易下跌。

  1. 在程式碼中寫分頁查詢邏輯時,若count為0應直接返回,避免執行後面的分頁語句。

  2. 不得使用外來鍵與級聯,一切外來鍵概念必須在應用層解決。說明:(概念解釋)學生表中的student_id是主鍵,那麼成績表中的student_id則為外來鍵。如果更新學生表中的student_id,同時觸發成績表中的student_id更新,則為級聯更新。外來鍵與級聯更新適用於單機低併發,不適合分散式、高併發叢集;級聯更新是強阻塞,存在資料庫更新風暴的風險;外來鍵影響資料庫的插入速度。

  1. 禁止使用儲存過程,儲存過程難以除錯和擴充套件,更沒有移植性。

  2. IDB資料訂正(特別是刪除或修改記錄操作)時,要先select,避免出現誤刪除,確認無誤才能提交執行。

  1. SQL語句中表的別名前加as,並且以t1、t2、t3、...的順序依次命名。說明:1)別名可以是表的簡稱,或者依據表在SQL語句中出現的順序,以t1、t2、t3的方式命名。2)別名前加as使別名更容易識別。正例:select t1.name from table_first as t1, table_second as t2 where t1.id=t2.id;

  2. in操作能避免則避免,若實在避免不了,需要仔細評估in後邊的集合元素數量,控制在1000個之內。

  1. 因國際化需要,所有的字元儲存與表示,均採用utf8字符集,那麼字元計數方法注意:說明:SELECT LENGTH("阿里巴巴");返回為12SELECT CHARACTER_LENGTH("阿里巴巴");返回為4如果需要儲存表情,那麼選擇utf8mb4來進行儲存,注意它與utf8編碼的區別。

   ORM規約

  1. 在表查詢中,一律不要使用 * 作為查詢的欄位列表,需要哪些欄位必須明確寫明。說明:1)增加查詢分析器解析成本。2)增減欄位容易與resultMap配置不一致。3)多餘欄位增加網路消耗,尤其是 text 型別的欄位。

  2. POJO類的布林屬性不能加is,而資料庫欄位必須加is_,要求在resultMap中進行欄位與屬性之間的對映。說明:參見定義POJO類以及資料庫欄位定義規定,在sql.xml增加對映,是必須的。

  3. 不要用resultClass當返回引數,即使所有類屬性名與資料庫欄位一一對應,也需要定義;反過來,每一個表也必然有一個與之對應。說明:配置對映關係,使欄位與DO類解耦,方便維護。

  4. sql.xml配置中引數注意:#{},#param# 不要使用${} 此種方式容易出現SQL注入。

  5. iBATIS自帶的queryForList(String statementName,int start,int size)不推薦使用。說明:其實現方式是在資料庫取到statementName對應的SQL語句的所有記錄,再通過subList取start,size的子集合,線上因為這個原因曾經出現過OOM。正例:在sqlmap.xml中引入 #start#, #size#

    Map<String, Object> map = new HashMap<>(16);  
    map.put("start", start);
    map.put("size", size);
  6. 不允許直接拿HashMap與HashTable作為查詢結果集的輸出。反例:某同學為避免寫一個xxx,直接使用HashTable來接收資料庫返回結果,結果出現日常是把bigint轉成Long值,而線上由於資料庫版本不一樣,解析成BigInteger,導致線上問題。

  7. 更新資料表記錄時,必須同時更新記錄對應的gmt_modified欄位值為當前時間。

   註釋規約

  1. 註釋的雙斜線與註釋內容之間有且僅有一個空格。正例:

    // 這是示例註釋,請注意在雙斜線之後有一個空格
    String commentString = new String();
  2. 類、類屬性、類方法的註釋必須使用javadoc規範,使用/**內容*/格式,不得使用//xxx方式。 說明:在IDE編輯視窗中,javadoc方式會提示相關注釋,生成javadoc可以正確輸出相應註釋;在IDE中,工程呼叫方法時,不進入方法即可懸浮提示方法、引數、返回值的意義,提高閱讀效率。

  3. 所有的抽象方法(包括介面中的方法)必須要用javadoc註釋、除了返回值、引數、異常說明外,還必須指出該方法做什麼事情,實現什麼功能。 說明:對子類的實現要求,或者呼叫注意事項,請一併說明。

  4. 所有的類都必須新增建立者資訊和建立日期。 說明:在設定模板時,注意IDEA的@author為${USER},而eclipse的@author為${user},大小寫有區別,而日期的設定統一為yyyy/MM/dd的格式。

    正例:

    /**

    @author wangchen(一律用花名)

    @date 2016/10/31  (yyyy/MM/dd)

    */

  5. 方法內部單行註釋,在被註釋語句上方另起一行,使用//註釋。方法內部多行註釋使用/ /註釋,注意與程式碼對齊。

  6. 所有的列舉型別欄位必須要有註釋,說明每個資料項的用途。

  7. 程式碼修改的同時,註釋也要進行相應的修改,尤其是引數、返回值、異常、核心邏輯等的修改。 說明:程式碼與註釋更新不同步,就像路網與導航軟體更新不同步一樣,如果導航軟體嚴重滯後,就失去了導航的意義。

  8. 在類中,刪除未使用的任何欄位和方法;在方法中,刪除未使用的任何引數宣告與內部變數。

  9. 對於註釋的要求:第一、能夠準確反映設計思想和程式碼邏輯;第二、能夠描述業務含義,使別的程式設計師能夠迅速瞭解到程式碼背後的資訊。完全沒有註釋的大段程式碼對於閱讀者形同天書,註釋是給自己看的,即使隔很長時間,也能清晰理解當時的思路;註釋也是給繼任者看的,使其能夠快速接替自己的工作。

  • 介面文件規約

  1. 公共統一:統一返回的response格式,比如使用CommonResult,統一返回的錯誤碼

  2. 聯調地址:測試環境地址,預發環境地址,生產環境地址;

  1. 介面規約:介面名稱,介面路徑,請求方式,請求入參(名稱,型別,是否空,欄位描述),請求入參樣例,返回引數(名稱,型別,欄位描述),返回引數樣例;

  2. 開發測試聯調流程:日常環境 -> 預發環境 -> 生產環境,資料庫同步環境:日常dev -> 預發 -> 生產

開發規約執行方法論

以上開發規約是基於《阿里巴巴 Java 開發手冊》整理的特殊化需求,雖然《手冊》是阿里巴巴集團技術團隊的集體智慧結晶和經驗總結, 經歷了多次大規模一線實戰的檢驗及不斷完善,系統化地整理成冊。當然,規範只能提供參考,我們還需要工具來幫忙我們實現了實時檢測。

   團隊間專案的程式碼複查

在專案上線之前,在前端團隊聯調之後,在測試團隊測試主體流程通過後,可以展開團隊間相互code review,這個過程時間控制在半天左右。比如當前專案由主coder開發,可以由其他專案成員review,反過來同理。這種方法相對消耗時間成本,當然也有接下來這種方式。

   使用外掛工具複查

目前,Alibaba Java Code Guidelines 外掛實現了開發手冊中的的 53 條規則,大部分基於 PMD 實現,其中有 4 條規則基於 IDEA 實現,並且基於 IDEA Inspection 實現了實時檢測功能。部分規則實現了 Quick Fix 功能。目前,外掛檢測有兩種模式:實時檢測、手動觸發。

IDEA 外掛地址: https://plugins.jetbrains.com/plugin/10046-alibaba-java-coding-guidelines

外掛檢查結果說明:

Blocker 、Critical 、Major 錯誤等級說明

Blocker: 即系統無法執行、崩潰或嚴重資源不足、應用模組無法啟動或異常退出、無法測試、造成系統不穩定。

  • 嚴重花屏

  • 記憶體洩漏

  • 使用者資料丟失或破壞

  • 系統崩潰/宕機/凍結

  • 模組無法啟動或異常退出

  • 嚴重的數值計算錯誤

  • 功能設計與需求嚴重不符

  • 其它導致無法測試的錯誤, 如伺服器500錯誤

Critical:即影響系統功能或操作,主要功能存在嚴重缺陷,但不會影響到系統穩定性。

  • 功能未實現

  • 功能錯誤

  • 系統重新整理錯誤

  • 資料通訊錯誤

  • 輕微的數值計算錯誤

  • 影響功能及介面的錯誤字或拼寫錯誤

  • 安全性問題

Major:即介面、效能缺陷、相容性。

  • 操作介面錯誤(包括資料視窗內列名定義、含義是否一致)

  • 邊界條件下錯誤

  • 提示資訊錯誤(包括未給出資訊、資訊提示錯誤等)

  • 長時間操作無進度提示

  • 系統未優化(效能問題)

  • 游標跳轉設定不好,滑鼠(游標)定位錯誤

  • 相容性問題

Minor/Trivial:即易用性及建議性問題。

  • 介面格式等不規範

  • 輔助說明描述不清楚

  • 操作時未給使用者提示

  • 可輸入區域和只讀區域沒有明顯的區分標誌

  • 個別不影響產品理解的錯別字

  • 文字排列不整齊等一些小問題

總結: Blocker > Critical > Major > Minor > Trivial  

Blocker,Critical是必須要修改的, Major根據具體建議情況參考處理, Minor和Trivial可以根據建議情況修補或者不修補。

   常見外掛一覽

  1. 快捷鍵提示工具:Key promoter X

    Key Promoter X 是一個快捷鍵提示外掛,如果滑鼠操作是能夠用快捷鍵替代,Key Promoter X 會提示可以用什麼快捷鍵替代。詳細使用文件,參考: https://plugins.jetbrains.com/plugin/9792-key-promoter-x

  1. 程式碼註解外掛:Lombok

lombok 的使用,參考 :https://projectlombok.org/。我們需要在程式碼中引入二方庫,然後安裝 lombok 外掛即可。

  1. 程式碼生成工具:CodeMaker

開發過程中,經常手工編寫重複程式碼。現在,可以通過 CodeMaker 來定義 Velocity 模版來支援自定義程式碼模板來生成程式碼。目前,CodeMaker 自帶兩個模板。Model:根據當前類生成一個與其擁有類似屬性的類,用於自動生成持久類對應的領域類。Converter:該模板需要兩個類作為輸入的上下文,用於自動生成領域類與持久類的轉化類。詳細使用文件,參考:https://github.com/x-hansong/CodeMaker

  1. 單元測試測試生成工具:JUnitGenerator

單元測試是必不可少的!我們可以使用 JUnitGenerator 外掛來自動建立了單元測試。我們可以使用提供的 velocity 模板定製單元測試輸出程式碼。如果在已經存在單元測試的地方建立了單元測試,則會提示使用者進行覆蓋或合併操作。合併操作允許使用者有選擇地建立目標檔案內容。詳細使用文件,參考:https://plugins.jetbrains.com/plugin/3064-junitgenerator-v2-0

  1. Mybatis 工具:Free Mybatis plugin

現在,MyBatis 框架已佔領半壁江山。因此,圍繞著 MyBatis 的外掛和工具越來越多。Free Mybatis plugin 非常方便進行 Mapper 介面和 XML 檔案之間跳轉。詳細使用文件,參考:

https://plugins.jetbrains.com/plugin/8321-free-mybatis-plugin。此外,收費版的還有 Mybatis plugin。

  1. Maven輔助神器:Maven Helper

如果 Maven 引入的 jar 包有衝突,可以使用 Maven Helper 外掛來幫助分析。詳細使用文件,參考:https://plugins.jetbrains.com/plugin/7179-maven-helper

  1. JSON轉領域物件工具:GsonFormat

在開發過程中,我們可能會遇到 json 格式的字串轉換成實體類引數的場景,這個外掛可以根據 JSONObject 格式的字串,自動生成實體類引數。詳細使用文件,參考:https://github.com/zzz40500/GsonFormat

  1. 領域物件轉JSON工具:POJO to JSON

為了測試需要,我們需要將簡單 Java 領域物件轉成 JSON 字串方便用 postman 或者 curl 模擬資料。詳細使用文件,參考:https://plugins.jetbrains.com/plugin/9686-pojo-to-json

  1. 時序圖生成工具:SequenceDiagram

有的時候,我們需要梳理業務邏輯或者閱讀原始碼。從中,我們需要了解整個呼叫鏈路,反向生成 UML 的時序圖是強需求。其中,SequenceDiagram 外掛是一個非常棒的外掛。詳細使用文件,參考:https://plugins.jetbrains.com/plugin/8286-sequencediagram

  1. 字串工具:String Manipulation

String Manipulation 外掛提供了非常豐富字串工具,例如命名替換( (camelCase, kebab-lowercase, KEBAB-UPPERCASE, snakecase, SCREAMINGSNAKE_CASE, dot.case, words lowercase, Words Capitalized, PascalCase)等。詳細使用文件,參考:https://plugins.jetbrains.com/plugin/2162-string-manipulation

  1. 程式碼作色工具:Rainbow Brackets

Rainbow Brackets 外掛可以實現配對括號相同顏色,並且實現選中區域程式碼高亮的功能。詳細使用文件,參考:https://plugins.jetbrains.com/plugin/10080-rainbow-brackets

  1. 日誌工具:Grep Console

參考:https://plugins.jetbrains.com/plugin/7125-grep-console

不同級別日誌通過顏色區分,一路瞭然。

  1. Redis視覺化:Iedis

參考:https://plugins.jetbrains.com/plugin/9228-iedis 使用參考:https://codesmagic.com/iedis/userguide/getting-started 可方便的執行增刪查改及使用命令列進行操作。

  1. 中英文翻譯工具:Translation

最騷的操作是什麼?帆哥在群裡分享了一套「半中文程式設計」:說到了變數命名,先用中文寫好,然後用 Translation 外掛的 translate and replace 一鍵替換為英文,這樣效率高而且準確。詳細使用文件,參考:https://plugins.jetbrains.com/plugin/8579-translation

   程式碼Review表格追蹤

應用

具體業務

開發人

Review人

Review結果/建議

Review日期

the-matrix

價格段洞察

開發人

組長

省略

省略

團隊介紹

新品平臺,打造新品全鏈路數智化引擎,致力於構建新品全鏈路的數字化工具和智慧化驅動品牌創新的技術體系,圍繞新品從市場研究、到產品研發、再到上市打爆的全生命週期,基於全域資料洞察,聯動產業生態,通過全鏈路的資料驅動、使用者共創和生態協同,幫助商家全面提升新品全鏈路效率和新品成功率,帶動規模優質新供給的創造和孵化,打造新品一站式孵化中心。

✿    拓展閱讀

作者 | 望沉

編輯| 橙子君

出品| 阿里巴巴新零售淘系技術