簡體   English   中英

Java中getter的命名約定有多重要?

[英]How important are naming conventions for getters in Java?

我非常相信一致性,因此也就是慣例。

但是,我目前正在開發一個Java框架,其中這些約定(特別是get / set前綴約定)似乎妨礙了可讀性。 例如,某些類將具有idname屬性,並且使用o.getId()而不是o.id()似乎完全沒有意義,原因如下:

  • 這些類是不可變的,因此(通常)沒有相應的setter,
  • 沒有混淆的可能性,
  • 在這種情況下, get不會傳達額外的語義,並且
  • 我用這個get稀少整個圖書館命名方案相當一致。

我從Java Collection類(以及Java Platform庫中的其他類)中得到了一些保證,這些類也違反了JavaBean約定(例如,它們使用size而不是getSize等)。

為了解決這個問題:組件永遠不會被用作JavaBean,因為它們不能以這種方式有意義地使用。

另一方面,我不是一個經驗豐富的Java用戶,我不知道其他Java開發人員對庫的期望。 我可以在這里遵循Java平台類的示例,還是被認為是糟糕的風格? 在Java庫類中違反get / set約定是否被認為是回想起來的錯誤? 或者在不適用時忽略JavaBean約定是完全正常的嗎?

JavaSun代碼約定根本沒有提到這一點。)

如果您遵循相應的命名約定,那么第三方工具可以輕松地與您的庫集成並使用您的庫。 他們會期待getX()isX()等,並嘗試通過反射找到它們。

雖然你說這些目前不會作為JavaBeans公開,但我仍然會遵循這些慣例。 誰知道你可能想要進一步做什么? 或者在稍后階段你可能想要提取這個對象的接口並創建一個可以通過其他工具訪問的代理?

我其實討厭這個慣例 如果它被一個提供accessor / modifier方法的真正的java工具所取代,我會發生這種情況。

但我在所有代碼中都遵循這個慣例 我們不單獨編程,即使整個團隊現在同意特殊約定,您也可以放心,未來的新人或將來維護您項目的團隊將在開始時遇到困難......我認為獲取/設置的不便並不像非標准的不便那么大。


我想提出另一個問題:java軟件經常使用太多的訪問器和修改器(get / set)。 我們應該更多地應用“ 告訴,不要問 ”的建議。 例如,用“真實”方法替換B上的getter:

    class A {
      B b;
      String c;
      void a() {
        String c = b.getC();
        String d = b.getD();
        // algorithm with b, c, d
      }
    }

通過

    class A {
      B b;
      String c;
      void a() {
        b.a(c); // Class B has the algorithm.
      }
    }

這個重構獲得了許多好的屬性:

  • B可以是不可變的(非常適合線程安全)
  • B的子類可以修改計算,因此B可能不需要另一個屬性用於此目的。
  • B中的實現比A更簡單,因為你不必使用getter和外部訪問數據,你在B里面並且可以利用實現細節(檢查錯誤,特殊情況,使用緩存的值...)。
  • 位於B中它具有更多耦合(兩個屬性而不是A的一個),重構A可能不會影響算法。 對於B重構,可能是改進算法的機會。 所以維護就少了。

違反Java庫類中的get / set約定肯定是一個錯誤。 我實際上建議你遵循慣例,以避免知道為什么/何時不遵守約定的復雜性。

喬希布洛赫其實在這個問題上與你雙方有效的Java ,他主張get的東西是注定不會被用作豆,為便於閱讀的緣故稀少變種。 當然,並不是每個人都同意布洛赫,但它表明有支持和反對傾銷案件get (我認為它更易於閱讀,因此,如果YAGNI,溝get )。

關於集合框架中的size()方法; 當您查看具有name()ordinal()最近的Enum類時,它似乎不太可能只是一個“壞”遺留名稱。 (這可能可以解釋為布洛赫是Enum的兩個歸屬作者之一.☺)

無差異模式在scala(和其他語言 )之類的語言中使用 ,具有統一訪問原則

Scala將字段和方法名稱保留在同一名稱空間中,這意味着如果方法名為count,我們就無法命名字段數。 許多語言(如Java)沒有此限制,因為它們將字段和方法名稱保存在不同的名稱空間中。

由於Java不是為“屬性”提供UAP,因此最好使用get / set約定來引用這些屬性。

UAP意味着:

  • Foo.barFoo.bar()是相同的並且引用讀取屬性或屬性的讀取方法。
  • Foo.bar = 5Foo.bar(5)是相同的,指的是設置屬性,或者指向屬性的write方法。

在Java中,您無法實現UAP,因為Foo.barFoo.bar()位於兩個不同的命名空間中。
這意味着要訪問read方法,您必須調用Foo.bar() ,這與調用任何其他方法沒有什么不同。
因此,這個get-set約定可以幫助區分該調用與其他調用(與屬性無關),因為“模塊提供的所有服務(此處只是讀取/設置值,或計算它”)無法通過統一符號“。
它不是強制性的,而是一種從其他服務中識別與獲取/設置或計算屬性值相關的服務的方法。
如果UAP在Java中可用,則根本不需要該約定。

注意: size()而不是getSize()可能是為了Java而保留的遺留錯誤命名的咒語是“向后兼容:始終”。

考慮一下:可以告訴許多框架引用對象字段中的屬性,例如“name”。 在框架下,框架理解為首先將“name”轉換為“setName”,從其單數參數中找出什么是返回類型,然后形成“getName”或“isName”。

如果您沒有提供這種記錄良好,合理的訪問器/更改器機制,那么您的框架/庫將無法與其他大多數庫/框架一起使用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM