溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

管理代碼里常量的方法是什么

發(fā)布時(shí)間:2021-10-12 15:01:56 來源:億速云 閱讀:126 作者:iii 欄目:編程語言

本篇內(nèi)容介紹了“管理代碼里常量的方法是什么”的有關(guān)知識,在實(shí)際案例的操作過程中,不少人都會(huì)遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

先看看前輩們是怎么做的

從事Web開發(fā),有個(gè)繞不開的常量就是HTTP的狀態(tài)碼,不如以此為起點(diǎn)

org.springframework.http.HttpStatus

①使用枚舉

public enum HttpStatus {
    CONTINUE(100, "Continue"),
    SWITCHING_PROTOCOLS(101, "Switching Protocols"),
    PROCESSING(102, "Processing"),
    CHECKPOINT(103, "Checkpoint"),
    OK(200, "OK"),
    CREATED(201, "Created"),
    ACCEPTED(202, "Accepted"),
    NON_AUTHORITATIVE_INFORMATION(203, "Non-Authoritative Information"),
    NO_CONTENT(204, "No Content"),
    ...

org.eclipse.jetty.http.HttpStatus

類中定義常量

public class HttpStatus {
    public static final int CONTINUE_100 = 100;
    public static final int SWITCHING_PROTOCOLS_101 = 101;
    public static final int PROCESSING_102 = 102;
    public static final int OK_200 = 200;
    public static final int CREATED_201 = 201;
    public static final int ACCEPTED_202 = 202;
    public static final int NON_AUTHORITATIVE_INFORMATION_203 = 203;
    public static final int NO_CONTENT_204 = 204;
    ...

org.apache.hc.core5.http.HttpStatus

final類中定義常量

public final class HttpStatus {
    public static final int SC_INFORMATIONAL = 100;
    public static final int SC_CONTINUE = 100;
    public static final int SC_SWITCHING_PROTOCOLS = 101;
    public static final int SC_PROCESSING = 102;
    public static final int SC_EARLY_HINTS = 103;
    public static final int SC_SUCCESS = 200;
    public static final int SC_OK = 200;
    public static final int SC_CREATED = 201;
    public static final int SC_ACCEPTED = 202;
    public static final int SC_NON_AUTHORITATIVE_INFORMATION = 203;
    public static final int SC_NO_CONTENT = 204;
    ...

以上都是在常用開源框架中的定義,在業(yè)務(wù)中還曾見過一種用法,是

在接口中定義常量

public interface HttpStatus {
    public static final int CONTINUE_100 = 100;
    public static final int SWITCHING_PROTOCOLS_101 = 101;
    public static final int PROCESSING_102 = 102;
    public static final int OK_200 = 200;
    public static final int CREATED_201 = 201;
    public static final int ACCEPTED_202 = 202;
    public static final int NON_AUTHORITATIVE_INFORMATION_203 = 203;
    public static final int NO_CONTENT_204 = 204;
    ...

這種接口被稱為常量接口,不過在《Effective Java》中的“接口只用于定義類型”這條建議中,特別批評了這種常量接口,認(rèn)為“常量接口模式是對接口的不良使用”。原文敘述如下:

The constant interface pattern is a poor use of interfaces. That a class uses some constants internally is an implementation detail. Implementing a constant interface causes this implementation detail to leak into the class’s exported API. It is of no consequence to the users of a class that the class implements a constant interface. In fact, it may even confuse them. Worse, it represents a commitment: if in a future release the class is modified so that it no longer needs to use the constants, it still must implement the interface to ensure binary compatibility. If a nonfinal class implements a constant interface, all of its subclasses will have their namespaces polluted by the constants in the interface.
常量接口模式是使用接口的糟糕方式。類內(nèi)部會(huì)使用一些常量,這是實(shí)現(xiàn)細(xì)節(jié)。然而,實(shí)現(xiàn)常量接口會(huì)導(dǎo)致這個(gè)實(shí)現(xiàn)細(xì)節(jié)泄漏到類的導(dǎo)出 API 中。對于類的用戶來說,類實(shí)現(xiàn)一個(gè)常量接口沒有什么價(jià)值。事實(shí)上,這甚至?xí)屗麄兏械嚼Щ?。更糟糕的是,它代表了一種承諾:如果在將來的版本中修改了類,使其不再需要使用常量,那么它仍然必須實(shí)現(xiàn)接口以確保二進(jìn)制兼容性。如果一個(gè)非 final 類實(shí)現(xiàn)了一個(gè)常量接口,那么它的所有子類的命名空間都會(huì)被接口中的常量所污染。

考慮到常量類不應(yīng)該被繼承,使用final要比沒有合適。

此外考慮到常量類應(yīng)該不需要被實(shí)例化,將構(gòu)造函數(shù)設(shè)置為private也是種額外的保護(hù)。

綜上,使用枚舉final常量類就是首選了,那么這兩者之間又如何抉擇呢?我們還是能從《Effective Java》得到有效的建議,第34條中就是在建議我們用枚舉替代int常量。

如何管理常量類

雖然枚舉是首選,但是常量類不會(huì)消失,常量不只是int常量,字符串常量也是日常開發(fā)中避不開的,而且有些時(shí)候我們還是會(huì)覺得常量更為便捷。那該如何管理這些常量呢?

常量的壞味道

1. 巨幅常量類

把程序中所有用到的常量,都集中放到一個(gè)Constants類中。這樣做會(huì)有一些缺點(diǎn),

  1. 為了增加常量會(huì)導(dǎo)致這個(gè)類的修改會(huì)很頻繁

  2. 依賴這個(gè)常量類的代碼會(huì)很多

  3. 為了使用某一個(gè)常量,會(huì)導(dǎo)致引入很多無關(guān)的常量

2. 重復(fù)的常量定義

作為職場新人的時(shí)候,我常干的一件事情就是重復(fù)定義常量,因?yàn)槲也恢绖e人是否定義過,在哪里定義過,與其要翻遍整個(gè)代碼庫去找這個(gè)常量,自己定義一個(gè)顯得方便的多。

直到有一天我需要去修改一個(gè)常量的定義,前面欠下的債就需要還了。重復(fù)代碼最大的問題就是,當(dāng)你需要去修改或者維護(hù)那段重復(fù)的代碼的時(shí)候,你需要去修改每一處,如果有遺漏,那就是bug了。重復(fù)常量也是如此。

管理思路

1. 定義多個(gè)功能單一的常量類

一個(gè)思路是按功能維度,去定義常量,一個(gè)常量類只跟某一功能相關(guān)。

MySQLConstants、RedisConstants。

但這個(gè)有個(gè)很虛的概念,就是功能,一個(gè)功能可大可小,范疇可以是某一個(gè)類,也可以是一整個(gè)模塊,這里沒有定論,依賴的就是程序員聰明的頭腦和豐富的經(jīng)驗(yàn)了。

2. 不單獨(dú)定義常量類

另外一種思路就是不單獨(dú)設(shè)計(jì)常量類,常量在哪個(gè)類里面使用,就把常量定義到這個(gè)類中。

比如在RedisClient和RedisConfig中都用到了之前RedisConstants中的常量,可以將其分別定義在RedisClient和RedisConfig中。

但這樣做有個(gè)明顯的問題就是,如果多個(gè)類用到了同一個(gè)常量,如果各自定義就造成了重復(fù),如果定義一份聲明為public,就會(huì)造成兩個(gè)類之間的依賴。這樣來看,在沒有復(fù)用訴求的情況下,就地定義才比較可取。

3. 按層次復(fù)用

上述兩種方式都沒有完整的解決我們的疑惑,考慮將上述兩種方式結(jié)合起來,可以得到一種按層次定義復(fù)用的方式。

  1. 跨應(yīng)用復(fù)用常量:放置在二方庫中,通常是client.jar中的constant目錄下。

  2. 應(yīng)用內(nèi)復(fù)用常量:放置在一方庫中,通常是common中的constant目錄下。

  3. 模塊內(nèi)部復(fù)用常量:即在當(dāng)前子工程的constant目錄下。

  4. 包內(nèi)復(fù)用常量:即在當(dāng)前包下單獨(dú)的constant目錄下。

  5. 類內(nèi)復(fù)用常量:直接在類內(nèi)部private static final定義。

“管理代碼里常量的方法是什么”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI