国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Java編程規(guī)范(代碼規(guī)范)--精選

這篇具有很好參考價(jià)值的文章主要介紹了Java編程規(guī)范(代碼規(guī)范)--精選。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

簡(jiǎn)介

說(shuō)明

本文介紹精選的Java編程規(guī)范(代碼規(guī)范)。遵守這些規(guī)范,代碼的bug數(shù)將會(huì)大幅減少,代碼可維護(hù)性、可讀性、擴(kuò)展性會(huì)大幅上升。(本文持續(xù)更新)

為什么要有編程規(guī)范?

編程規(guī)范有如下作用:

  1. 提高代碼可讀性、維護(hù)性、擴(kuò)展性
  2. 提高開(kāi)發(fā)速度、減少bug
  3. 有助于留住人才(接手別人的垃圾代碼占離職原因的很大一部分)

好的編程規(guī)范是怎樣的?

  1. 規(guī)范要精簡(jiǎn),否則不利于普及

規(guī)范的落實(shí)

  1. 編程規(guī)范要配合代碼審核,否則都是空話。
  2. 代碼審核必須在代碼提測(cè)之前進(jìn)行。(因?yàn)槿绻麥y(cè)試通過(guò)了,由于不符合編程規(guī)范再改動(dòng)的話,需要費(fèi)時(shí)間進(jìn)行回歸測(cè)試,導(dǎo)致影響上線)
  3. 代碼評(píng)審要以平臺(tái)的方式進(jìn)行:被評(píng)審者將代碼提到評(píng)審平臺(tái),然后評(píng)審者在此平臺(tái)進(jìn)行批注,被評(píng)審者進(jìn)行代碼修改。
    1. 這種代碼評(píng)審基本是毫無(wú)卵用的:多個(gè)人聚在一個(gè)會(huì)議室里,盯著一個(gè)電腦投屏進(jìn)行評(píng)審。
  4. 代碼規(guī)范要加入績(jī)效考核(占比在1%~5%之間),否則無(wú)法引起重視。
    1. 好的大公司就是這么做的,代碼極好,擴(kuò)展性極好,技術(shù)氛圍極好,項(xiàng)目的質(zhì)量極好、用戶的反饋極好...

格式

  1. 單個(gè)方法不能超過(guò)60行,如果超過(guò)必須拆分
    1. IDEA大概能顯示40行代碼,60行對(duì)一個(gè)方法來(lái)說(shuō)肯定是夠用的。
    2. 反例:所有邏輯堆在一個(gè)方法里,單個(gè)方法成百上千行
  2. 單行代碼不能超過(guò)100個(gè)字符(包括空格),如果超過(guò)必須換行。換行時(shí)遵循如下原則:
    1. 第二行相對(duì)第一行縮進(jìn) 4 個(gè)空格;從第三行開(kāi)始,不再繼續(xù)縮進(jìn)
    2. 運(yùn)算符與下文一起換行;方法調(diào)用的點(diǎn)符號(hào)與下文一起換行
  3. if/for/while/switch/do 等保留字與括號(hào)之間必須加空格。

命名

  1. 命名可以很長(zhǎng),不能為了縮短長(zhǎng)度進(jìn)行單詞的簡(jiǎn)寫(xiě)(提高可讀性)。(例外:接口實(shí)現(xiàn)類以Impl結(jié)尾等通用的縮寫(xiě))
    1. 正例:interfaceOperationCode
    2. 反例:intOpCode
  2. 字段名第一個(gè)字母必須小寫(xiě)。
    • 重大bug:用lombok,若前兩個(gè)字母大寫(xiě),用Jackson序列化時(shí)第二個(gè)大寫(xiě)會(huì)變成小寫(xiě)。
  3. 類名和包名使用單數(shù)形式,但是如果類名有復(fù)數(shù)含義,類名可以使用復(fù)數(shù)形式
    1. 正例:com.abc.user.detail
    2. 反例:com.abc.users.detail
  4. 包名統(tǒng)一使用小寫(xiě),點(diǎn)分隔符之間有且僅有一個(gè)自然語(yǔ)義的英語(yǔ)單詞。如果必須要用兩個(gè)單詞,也都要小寫(xiě)
    1. 正例 : com.alibaba.open.util、com.abc.userdetail
  5. 抽象類命名使用Abstract開(kāi)頭;異常類命名用Exception結(jié)尾;接口類命名不要添加無(wú)用的前綴與后綴(比如:I開(kāi)頭、Interface結(jié)尾)
  6. POJO類中布爾類型變量不要加is前綴,否則部分框架解析會(huì)引起序列化錯(cuò)誤。
    1. 反例:將是否刪除定義為:Boolean isDeleted
    2. 正例:將是否刪除定義為:Boolean deletedFlag
  7. Controller的url命名規(guī)范:
    1. 駝峰命名。
    2. 統(tǒng)一是這種:/表名/增刪改查,比如:用戶詳情的增加接口:/userDetail/add。增刪改查對(duì)應(yīng)的英文如下:
      1. 增加:add
      2. 編輯:edit
      3. 刪除:delete
      4. 分頁(yè)查詢:page
      5. 列表查詢:list

常量

  1. 不要使用一個(gè)常量類維護(hù)所有常量,應(yīng)該按常量功能進(jìn)行歸類,分開(kāi)維護(hù)(提高可維護(hù)性)。
    1. 正例:緩存相關(guān)的常量: CacheConstant;配置相關(guān)的常量: ConfigConstant。
  2. 常量命名全部大寫(xiě),單詞間用下劃線隔開(kāi)。
    1. 正例 : MAX_STOCK_COUNT
    2. 反例 : Max_Stock_Count

類型

  1. 禁止使用Map作為方法的入?yún)⒒蚍祷刂担仨毷褂脤?duì)象明確列出所有字段。(例外:有些地方只能是Map類型,比如:短信發(fā)送接口,參數(shù)是不確定的,調(diào)用方自定義key和value)
    1. 反例:給別人提供Feign接口時(shí),返回值是Map類型。
    2. 正例:定義一個(gè)XxxVO,將字段寫(xiě)到XxxVO里,作為接口返回值。
    3. 正例:查很多用戶詳情時(shí),為提高接口速度,將單個(gè)SQL轉(zhuǎn)成批量SQL(將多個(gè)=轉(zhuǎn)化成單個(gè)IN),然后將其結(jié)果轉(zhuǎn)成key為用戶id,value為用戶數(shù)據(jù)的Map,再進(jìn)行后續(xù)操作。
  2. 如果代碼內(nèi)部用到了Map,必須在map定義處寫(xiě)明key和value分別是什么。
  3. 這些地方必須使用包裝數(shù)據(jù)類型:所有的 POJO 類屬性、RPC 方法的返回值和參數(shù)
    1. 即:要用Integer、Long等,不要用int、long
  4. 實(shí)體類不要implements?Serializable
    1. Serializable是序列化,現(xiàn)在都是使用JSON了,不要再實(shí)現(xiàn)Serializable了!(題外話:寫(xiě)代碼時(shí)要思考,看究竟有什么用,不明白的就去搞明白,不要糊里糊涂地寫(xiě))。
    2. 當(dāng)然,有時(shí)候就必須要實(shí)現(xiàn)Serializable,比如:Dubbo的實(shí)體類,默認(rèn)用的是Serializable的序列化來(lái)傳遞數(shù)據(jù),所以必須實(shí)現(xiàn)Serializable。

參數(shù)與返回值

  1. 不能修改入?yún)?duì)象的字段,如果要修改,必須新創(chuàng)建一個(gè)對(duì)象
    1. 例外:如果方法就是為了給入?yún)?duì)象賦值的,可以去修改。
  2. 方法入?yún)⒌膫€(gè)數(shù)必須小于5
    1. 如果大于等于5,必須將入?yún)⒎庋b為一個(gè)類。
  3. 分頁(yè)接口的請(qǐng)求和響應(yīng)必須繼承公共父類,如下:

分頁(yè)的請(qǐng)求類

import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.time.LocalDateTime;

@Data
public class PageRequest {
    @ApiModelProperty("當(dāng)前頁(yè)")
    private Long currentPage = 0L;

    @ApiModelProperty("每頁(yè)個(gè)數(shù)")
    private Long pageSize = 10L;

    @ApiModelProperty("創(chuàng)建時(shí)間開(kāi)始")
    private LocalDateTime createTimeStart;

    @ApiModelProperty("創(chuàng)建時(shí)間結(jié)束")
    private LocalDateTime createTimeEnd;
}

分頁(yè)的響應(yīng)類

import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.util.List;

@Data
public class PageResponse<T> {
    @ApiModelProperty("當(dāng)前頁(yè)")
    private Long currentPage = 0L;

    @ApiModelProperty("每頁(yè)個(gè)數(shù)")
    private Long pageSize = 10L;

    @ApiModelProperty("總個(gè)數(shù)")
    private Long totalSize = 0L;

    private List<T> dataList;
}

注釋

  1. 所有接口說(shuō)明都使用knife4j的,不要重復(fù)寫(xiě)注釋。
  2. 方法注釋中沒(méi)用的說(shuō)明要?jiǎng)h掉,比如:參數(shù)后如果沒(méi)加詳細(xì)說(shuō)明,就把這行參數(shù)注釋刪掉。
  3. 文件前不要讓Idea自動(dòng)生成創(chuàng)建時(shí)間、創(chuàng)建人。
    1. 原因:這是多余的操作,git已經(jīng)記錄了此文件的創(chuàng)建人和創(chuàng)建時(shí)間

復(fù)用

  1. 邏輯重復(fù)的代碼要抽取為同一個(gè)(提高復(fù)用性)
    1. 正例:頁(yè)面上的分頁(yè)查詢、Excel導(dǎo)出查詢的數(shù)據(jù),這兩個(gè)共用查數(shù)據(jù)的方法。

單一職責(zé)

  1. 每個(gè)接口的參數(shù)和返回值必須是獨(dú)立的。
    1. 比如:查詢用戶的入?yún)⒑头祷刂凳牵篣serPageQueryBO,UserPageQueryVO;保存用戶的入?yún)⒑头祷刂凳牵篣serSaveBO,UserSaveVO。雖然UserPageQueryBO和UserSaveBO會(huì)有很多重復(fù)的字段,但也不能合并為一個(gè)BO。如果進(jìn)行了合并,會(huì)有如下致命缺點(diǎn):
      1. 看接口入?yún)o(wú)法確定用到了哪些字段,必須看代碼實(shí)現(xiàn)才能確定,極不清晰。
      2. 接口文檔不清晰,當(dāng)導(dǎo)出接口文檔時(shí),前端開(kāi)發(fā)人員也不好分辨。
    2. 此情況例外:功能極其接近時(shí)允許用同一個(gè)參數(shù)和返回值。
      1. 比如查詢用戶需要提供兩個(gè)接口:分頁(yè)查詢和全量查詢,此時(shí)可以共用查詢?nèi)雲(yún)ⅲ瑢⑵涠x為:UserQueryBO。
  2. 每個(gè)類的字段必須是有效的
    1. 比如:查詢用戶的入?yún)?shí)體類里,只包含必須的字段,比如:用戶名、手機(jī)號(hào),不要包含用不到的字段,比如:用戶id,用戶的密碼。

數(shù)據(jù)庫(kù)

注意事項(xiàng)

  1. 狀態(tài)、類型等字段Java代碼使用枚舉類型,數(shù)據(jù)庫(kù)必須使用字符串(提高可維護(hù)性)
    1. 具體方法見(jiàn):SpringBoot--在Entity(DAO)中使用枚舉類型_IT利刃出鞘的博客-CSDN博客
  2. 創(chuàng)建時(shí)間、更新時(shí)間、是否刪除等字段,必須放到列的最后。(提高可讀性)
    1. 后邊如果有新加的字段,要加在這些字段之前,永遠(yuǎn)保持這些字段在最后!
  3. 主鍵ID一律使用MyBatis-Plus自帶的雪花算法來(lái)生成。(有利于數(shù)據(jù)庫(kù)遷移等)
  4. 查數(shù)據(jù)的方式要最優(yōu),如下方式要優(yōu)先考慮前邊的方式。
    1. lambdaQuery、在代碼中用字符串拼MyBatis-Plus條件(用字符串指定字段名)、Mapper中寫(xiě)注解、在XML中寫(xiě)。
  5. 查數(shù)據(jù)時(shí)盡量不要聯(lián)表查。(因?yàn)閿?shù)據(jù)量大時(shí),聯(lián)表查會(huì)很慢)。

建表的必要字段

說(shuō)明

為了便于排查問(wèn)題,建表時(shí)需要加一些必要的字段:創(chuàng)建人、更新人、創(chuàng)建時(shí)間、更新時(shí)間、刪除標(biāo)記。

SQL

ALTER TABLE `庫(kù)名`.`表名` 
ADD COLUMN `id` bigint NOT NULL COMMENT '主鍵',
ADD COLUMN `create_time` datetime NOT NULL COMMENT '創(chuàng)建時(shí)間',
ADD COLUMN `update_time` datetime NOT NULL COMMENT '修改時(shí)間',
ADD COLUMN `create_id` varchar(32) COMMENT '創(chuàng)建人ID',
ADD COLUMN `create_name` varchar(32) COMMENT '創(chuàng)建人ID',
ADD COLUMN `update_id` varchar(32) COMMENT '修改人名字',
ADD COLUMN `update_name` varchar(32) COMMENT '修改人名字',
ADD COLUMN `delete_flag` bigint NOT NULL DEFAULT 0 COMMENT '刪除標(biāo)記。0:未刪除;其他:已刪除';

詳解

  • 創(chuàng)建時(shí)間和更新時(shí)間的字段名
    • 阿里開(kāi)發(fā)手冊(cè)的規(guī)范:
      • 嵩山版、華山版等:表必備三字段:id,create_time,update_time。(推薦)
      • 泰山版等:表必備三字段:id,gmt_create,gmt_modified。(不推薦)
    • 注意:時(shí)間相關(guān)的字段名應(yīng)該有“time”才好。而且有一些Mock工具(例如:ApiFox)會(huì)根據(jù)字段名自動(dòng)構(gòu)造假數(shù)據(jù),字段中帶“time”工具就會(huì)自動(dòng)生成很接近實(shí)際的mock數(shù)據(jù),有利于前端自測(cè)代碼。
  • 更新時(shí)間不要設(shè)置為自動(dòng)更新
    • 不要讓更新時(shí)間自動(dòng)更新,即:不要這樣寫(xiě):ADD COLUMN `update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '修改時(shí)間',
    • 原因:
      • 數(shù)據(jù)庫(kù)服務(wù)器很可能沒(méi)有正確設(shè)置時(shí)區(qū),如果“更新時(shí)間”字段使用了數(shù)據(jù)庫(kù)服務(wù)器的時(shí)區(qū)進(jìn)行了自動(dòng)更新,那這個(gè)時(shí)間就是不正確的。
      • 以我工作的幾家公司來(lái)看,數(shù)據(jù)庫(kù)服務(wù)器的時(shí)區(qū)基本都是錯(cuò)誤的。
    • 正確的方法是:“創(chuàng)建時(shí)間”和“更新時(shí)間”全部通過(guò)應(yīng)用來(lái)自動(dòng)生成。比如MybatisPlus的自動(dòng)填充:MyBatis-Plus--自動(dòng)填充的用法_IT利刃出鞘的博客-CSDN博客
  • 刪除標(biāo)記不要使用0,1來(lái)表示,在刪除時(shí)應(yīng)該將id的值賦值給delete_flag
    • 如果用0,1表示,會(huì)影響唯一索引。見(jiàn):MyBatis-Plus--解決邏輯刪除與唯一索引的問(wèn)題--方法/實(shí)例_IT利刃出鞘的博客-CSDN博客
  • 數(shù)據(jù)庫(kù)的時(shí)間字段對(duì)應(yīng)的Java的DAO的字段類型要用LocalDateTime
    • 現(xiàn)在21世紀(jì)了,不要再用Date了。
    • LocalDateTime的優(yōu)點(diǎn):
      • 可明確知曉:這是個(gè)日期+時(shí)間的字段。(Date不能一眼看出是日期還是時(shí)間還是兩者)
      • LocalDateTime的格式化等操作是線程安全的。
      • LocalDateTime的方法很豐富。

上邊的字段必須有公共的實(shí)體類(CommonEntity),使用Xxx extends CommonEntity的方式,不要在自己實(shí)體類手寫(xiě)這些字段。

CommonEntity如下:

package com.example.knife.common.entity;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;

import lombok.Data;

import java.time.LocalDateTime;

/**
 * 數(shù)據(jù)庫(kù)公共實(shí)體類
 */
@Data
public class CommonEntity {
    /**
     * 主鍵
     */
    @TableId(type = IdType.ASSIGN_ID)
    private Long id;

    /**
     * 創(chuàng)建時(shí)間
     */
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;

    /**
     * 修改時(shí)間
     */
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;

    /**
     * 創(chuàng)建人ID
     */
    private String createId;

    /**
     * 創(chuàng)建人名字
     */
    private String createName;

    /**
     * 更新人ID
     */
    private String updateId;

    /**
     * 更新人名字
     */
    private String updateName;

    /**
     * 刪除標(biāo)記。0:未刪除;其他:已刪除
     */
    @TableLogic("id")
    private Long deleteFlag;
}

API選用

  1. 時(shí)間類型必須使用JDK8的類型,比如:LocalDateTime,LocalDate,LocalTime
    1. 不要使用Date類型(Date的API難用,Date含義不清晰(不知道是日期還是時(shí)間)多線程格式化時(shí)要考慮線程安全等)。這老一套的東西該摒棄了。
  2. 小數(shù)數(shù)字類型必須使用BigDecimal。
    1. double和float會(huì)失真。
    2. BigDecimal使用時(shí)也要小心,盡量學(xué)一下再用,它還是要注意一些問(wèn)題的,比如:若不指定精度,除不盡的算術(shù)操作會(huì)拋異常。詳見(jiàn):Java之BigDecimal系列--使用/教程/實(shí)例_IT利刃出鞘的博客-CSDN博客
    3. 題外話:對(duì)于IT來(lái)說(shuō),不是說(shuō)知道某個(gè)技術(shù)就行了,而要深入下去,無(wú)論是普通的API還是高級(jí)技術(shù),無(wú)論是哪個(gè)技術(shù)都有需要注意的地方,都可能有坑。如果對(duì)技術(shù)淺嘗輒止,那么就很難進(jìn)步,很可能就是一年的經(jīng)驗(yàn)用十年,難以成長(zhǎng)為技術(shù)大佬。
  3. Lombok的使用
    1. 不要使用@Accessors,可以使用@Builder
      1. 為了方便給字段賦值,lombok提供了一些注解,但不要用@Accessors,因?yàn)樗傻膕et方法有返回值,會(huì)存在問(wèn)題:有些中間件會(huì)判斷方法是否有返回值進(jìn)而進(jìn)行操作,比如:EasyExcel。(如果使用了@Accessors,會(huì)導(dǎo)致導(dǎo)入Excel時(shí)取不到值)
      2. 題外話:lombok等中間件固然很方便,但任何API都要選用,不要全部采用。其中一個(gè)重要的原則就是:不要改變正常的邏輯,比如:set方法就不應(yīng)該有返回值。
  4. 要使用@Autowired,不要用@Resource。
    1. Spring的項(xiàng)目,就盡量用Spring的東西。

技術(shù)選型

必須使用主流且穩(wěn)定的技術(shù)棧(見(jiàn):Java后端開(kāi)發(fā)技術(shù)選型_IT利刃出鞘的博客-CSDN博客)

不得使用如下技術(shù)(如下技術(shù)都有穩(wěn)定、成熟的同類技術(shù)可以替代):

不穩(wěn)定,bug多的技術(shù)

  1. fastjson
  2. hutool

資源消耗很大的技術(shù)

  1. FileBeat

全局處理

異常

  1. 必須將錯(cuò)誤信息作為異常拋出來(lái),讓全局異常處理器去處理。
    1. 不能自己返回錯(cuò)誤信息。(會(huì)增加代碼的復(fù)雜度,如果代碼有多個(gè)調(diào)用,層層傳遞錯(cuò)誤信息會(huì)無(wú)法維護(hù))
    2. 不能自己捕獲了異常然后不處理信息。(會(huì)導(dǎo)致無(wú)法排查問(wèn)題)

包裝返回值給前端

  1. 自己不要去包裝返回值給前端,由AOP統(tǒng)一去包裝。(減少代碼量,便于維護(hù))

feign調(diào)用文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-454898.html

  1. 自己不要去包裝返回值給調(diào)用方,由AOP統(tǒng)一去包裝。(減少代碼量,便于維護(hù))
  2. 調(diào)用方不要手動(dòng)去解析包裝數(shù)據(jù),需要由統(tǒng)一的解碼器去處理。

邏輯

  1. json字符串解析為對(duì)象
    1. 一個(gè)json字符串必須有一個(gè)完全對(duì)應(yīng)的java對(duì)象。(代碼可讀性高)
    2. 必須一步到位將json字符串解析為整個(gè)java對(duì)象,不能解析完外層再解析內(nèi)層。
  2. get方法不能有其他邏輯,必須直接返回字段本身。
  3. 如果必須要手動(dòng)捕獲異常,必須要輸出詳細(xì)堆棧 將堆棧打出來(lái)
    1. 如果有日志組件,必須使用日志組件。
    2. 如果沒(méi)有日志組件,用log.error("xxx", e);?
  4. 所有地方必須判斷null
    1. 如果是null,必須拋出異常,信息為:xxx不能為null。
  5. 禁止將業(yè)務(wù)對(duì)象作為Map的key,禁止覆寫(xiě)equals和hashCode。
    • 因?yàn)閯e人也會(huì)用這個(gè)業(yè)務(wù)對(duì)象,改了這些會(huì)導(dǎo)致別人的業(yè)務(wù)出問(wèn)題!

其他

  1. 代碼中不得存在被IDEA警告的代碼,若存在則必須看IDEA的提示并進(jìn)行修改。(包括:錯(cuò)的單詞拼寫(xiě),泛型警告,優(yōu)化的提示等)

到了這里,關(guān)于Java編程規(guī)范(代碼規(guī)范)--精選的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包