Jaki jest najlepszy sposób na implementację stałych w Javie? [Zamknięte]

372

Widziałem takie przykłady:

public class MaxSeconds {
   public static final int MAX_SECONDS = 25;
}

i przypuszczałem, że mógłbym mieć klasę Constans do zawijania stałych, deklarując je jako statyczne końcowe. Praktycznie nie znam żadnej Javy i zastanawiam się, czy to najlepszy sposób na tworzenie stałych.

mk.
źródło

Odpowiedzi:

403

Jest to całkowicie do przyjęcia, prawdopodobnie nawet standard.

(public/private) static final TYPE NAME = VALUE;

gdzie TYPEjest typ, NAMEnazwa we wszystkich wielkich literach z podkreślnikami dla spacji i VALUEjest wartością stałą;

Zdecydowanie NIE polecam umieszczać stałych we własnych klasach lub interfejsach.

Na marginesie: Zmienne, które zostały zadeklarowane jako ostateczne i można je modyfikować, można nadal zmieniać; zmienna nie może jednak nigdy wskazywać innego obiektu.

Na przykład:

public static final Point ORIGIN = new Point(0,0);

public static void main(String[] args){

    ORIGIN.x = 3;

}

Jest to zgodne z prawem i ORIGINoznaczałoby punkt (3, 0).

jjnguy
źródło
19
Możesz nawet „importować statyczne MaxSeconds.MAX_SECONDS;” żebyś nie musiał przeliterować MaxSeconds.MAX_SECONDS
Aaron Maenpaa
23
Poprzedni komentarz dotyczący importu statycznego dotyczy tylko Java 5+. Niektórzy uważają, że skrót nie jest wart ewentualnego zamieszania co do tego, skąd pochodzi ta stała, podczas czytania długiego kodu MaxSeconds.MAX_SECONDS może być łatwiejsze do śledzenia niż przeglądanie importu.
MetroidFan2002
5
Ponieważ możesz zmienić objetc, jak pokazali jjnguy, najlepiej jest, jeśli twoje constatns są niezmiennymi obiektami lub zwykłymi prymitywami / łańcuchami.
marcospereira
14
Jeśli czytasz to pytanie, przeczytaj poniższe dwie odpowiedzi, zanim podejmiesz tę odpowiedź zbyt poważnie, mimo że zostanie zaakceptowana, jest kontrowersyjna, jeśli nie błędna.
orbfish
3
@ jjnguy się nie mylisz, ale jeśli przeczytam tylko pytanie i kilka pierwszych linii twojej odpowiedzi, odniosę wrażenie, że „klasa stałych” jest „całkowicie do zaakceptowania, prawdopodobnie nawet standardowa”. To pojęcie jest błędne.
Zach Lysobey
235

Odradzam posiadanie jednej klasy stałych. W tej chwili może się to wydawać dobrym pomysłem, ale gdy programiści odmawiają udokumentowania stałych, a klasa rośnie w górę w stosunku do 500 stałych, które w ogóle nie są ze sobą powiązane (są związane z zupełnie innymi aspektami aplikacji), to generalnie zamienia się w plik stałych, który jest całkowicie nieczytelny. Zamiast:

  • Jeśli masz dostęp do Java 5+, użyj wyliczeń, aby zdefiniować określone stałe dla obszaru aplikacji. Wszystkie części obszaru zastosowania powinny odnosić się do wyliczeń, a nie wartości stałych, dla tych stałych. Możesz zadeklarować wyliczenie podobne do sposobu deklarowania klasy. Wyliczenia są prawdopodobnie najbardziej (i prawdopodobnie jedyną) przydatną funkcją Java 5+.
  • Jeśli masz stałe, które są poprawne tylko dla określonej klasy lub jednej z jej podklas, zadeklaruj je jako chronione lub publiczne i umieść je w najwyższej klasie w hierarchii. W ten sposób podklasy mogą uzyskiwać dostęp do tych stałych wartości (a jeśli inne klasy uzyskują dostęp do nich publicznie, stałe nie są ważne tylko dla konkretnej klasy ... co oznacza, że ​​klasy zewnętrzne używające tej stałej mogą być zbyt ściśle powiązane z klasa zawierająca stałą)
  • Jeśli masz interfejs ze zdefiniowanym zachowaniem, ale zwracane wartości lub wartości argumentów powinny być szczególne, całkowicie dopuszczalne jest zdefiniowanie stałych w tym interfejsie, aby inni implementatorzy mieli do nich dostęp. Unikaj jednak tworzenia interfejsu wyłącznie do przechowywania stałych: może stać się tak samo zły jak klasa stworzona tylko do przechowywania stałych.
MetroidFan2002
źródło
12
całkowicie się zgadzam ... można to udokumentować jako klasyczny anty-wzór dla dużych projektów.
Das
30
Nie na temat, ale ... Generics z pewnością nie są idealne, ale myślę, że można by zrobić całkiem dobry argument, że są one użyteczną funkcją Java 5 :)
Martin McNulty
3
@ ŁukaszL. Samo pytanie naprawdę opiera się na opiniach (ilekroć pojawia się „najlepsze”, zazwyczaj jest to kwestia opinii), więc odpowiedź jest prawidłową odpowiedzią na to pytanie. Udzieliłem odpowiedzi na pytanie, co (tak, sądzę , że tak, więc tak, jest to opinia, ponieważ znowu „najlepsza” zmiana zmienia się w czasie i ogólnie jest oparta na opiniach) najlepszym sposobem implementacji stałych w Javie.
MetroidFan2002
1
Żadna z powyższych opcji nie daje prawdziwej zmiennej globalnej. Co jeśli mam coś, co jest używane wszędzie, ale nie jest wyliczeniem? Czy wyliczam tylko jedną rzecz?
markthegrea
1
Jeśli potrzebujesz stałej globalnej obejmującej wszystkie moduły, prawdopodobnie coś jest nie tak z twoją strategią projektowania. Jeśli naprawdę potrzebujesz stałej globalnej, zrób dla niej publiczną klasę końcową w pakiecie najwyższego poziomu i tam ją trzymaj. Następnie usuń go, gdy tylko zdasz sobie sprawę, że nie wszystkie twoje klasy rzeczywiście potrzebują tej stałej i przenieś ją do pakietu, który najbardziej ją odwołuje. Możesz współdzielić stałą między pakietami, ale to zapach kodu wymaga stałej globalnej, która nie jest typem wyliczanym, ponieważ typy wyliczane mogą mieć zachowanie, ale łańcuch jest łańcuchem, int jest
intem
120

ZŁA PRAKTYKA polega na używaniu interfejsów tylko do przechowywania stałych (nazwanych stałym wzorcem interfejsu przez Josha Blocha). Oto, co radzi Josh:

Jeśli stałe są silnie powiązane z istniejącą klasą lub interfejsem, należy dodać je do klasy lub interfejsu. Na przykład wszystkie klasyczne pierwotne klasy liczbowe w pudełkach, takie jak Integer i Double, eksportują stałe MIN_VALUE i MAX_VALUE. Jeśli stałe najlepiej postrzegać jako elementy typu wyliczanego, należy je wyeksportować z typem wyliczenia . W przeciwnym razie należy wyeksportować stałe z nieinstantowalną klasą narzędzia.

Przykład:

// Constant utility class
package com.effectivejava.science;
public class PhysicalConstants {
    private PhysicalConstants() { }  // Prevents instantiation

    public static final double AVOGADROS_NUMBER   = 6.02214199e23;
    public static final double BOLTZMANN_CONSTANT = 1.3806503e-23;
    public static final double ELECTRON_MASS      = 9.10938188e-31;
}

Informacje o konwencji nazewnictwa:

Zgodnie z konwencją takie pola mają nazwy składające się z wielkich liter, a słowa oddzielone są podkreślnikami. Bardzo ważne jest, aby pola te zawierały pierwotne wartości lub odniesienia do niezmiennych obiektów.

Marcio Aguiar
źródło
23
Jeśli zamierzasz nazwać coś złą praktyką, być może powinieneś wyjaśnić, dlaczego tak uważasz?
GlennS,
14
To jest stary post, ale lepiej używać abstractnotacji dla klasy zamiast prywatnego konstruktora.
Xtreme Biker
5
Matt, chociaż zalecenie rowerzysty nie jest fałszywe, zalecałbym raczej zajęcia końcowe, a nie abstrakcyjne. Rowerzysta powiedział, że chcesz upewnić się, że twoja klasa stałych nie jest zmienna. Oznaczając go jako ostateczny, nie zezwala się na jego podklasę ani tworzenie instancji. Pomaga to również zawrzeć jego statyczną funkcjonalność i nie pozwala innym programistom na podklasowanie go i zmuszanie go do robienia rzeczy, do których nie został zaprojektowany.
liltitus27,
7
@XtremeBiker Oznaczenie klasy abstractzamiast prywatnego konstruktora nie zapobiega całkowicie tworzeniu instancji, ponieważ można ją podklasować i utworzyć instancję podklasy (nie jest to dobry pomysł, ale jest to możliwe). @ToolmakerSteve Nie można podklasować klasy prywatnym konstruktorem (przynajmniej nie bez dużego złego hakowania), ponieważ konstruktor tej podklasy musi wywoływać (obecnie prywatny) konstruktor swojej nadklasy. Oznaczenie go finaljest więc niepotrzebne (ale być może bardziej wyraźne).
zaimportuj ten
3
Jeszcze gorzej jest używać klasy tylko do przechowywania stałych. Jeśli nigdy nie chcesz tworzyć obiektu tej klasy, dlaczego używasz zwykłej klasy ?
MaxZoom
36

W Effective Java (2. edycja) zaleca się stosowanie wyliczeń zamiast stałych int dla stałych.

Tutaj jest dobry opis wyliczeń w Javie: http://java.sun.com/j2se/1.5.0/docs/guide/language/enums.html

Zauważ, że na końcu tego artykułu postawiono pytanie:

Kiedy więc należy stosować wyliczenia?

Z odpowiedzią:

Za każdym razem, gdy potrzebujesz stałego zestawu stałych

Sheloo
źródło
21

Po prostu unikaj używania interfejsu:

public interface MyConstants {
    String CONSTANT_ONE = "foo";
}

public class NeddsConstant implements MyConstants {

}

To kuszące, ale narusza enkapsulację i zaciera rozróżnienie definicji klas.


źródło
1
Rzeczywiście, import statyczny jest zdecydowanie lepszy.
Aaron Maenpaa,
1
Ta praktyka jest dziwnym zastosowaniem interfejsów, które mają na celu określenie usług świadczonych przez klasę.
Rafa Romero
1
Nie zgadzam się z unikaniem używania interfejsu dla stałych, ale myślę, że twój przykład wprowadza w błąd. Nie musisz implementować interfejsu, aby uzyskać dostęp do stałej, ponieważ jest ona domyślnie statyczna, publiczna i końcowa. Więc jest to prostsze niż tutaj opisałeś.
djangofan
To prawda ... to narusza enkapsulację, wolę używać końcowej klasy Constant, która wygląda bardziej obiektowo i jest lepsza niż interfejs OR enum . Uwaga: Enum można uniknąć, jeśli Android nie jest potrzebny.
CoDe
19

Stosuję następujące podejście:

public final class Constants {
  public final class File {
    public static final int MIN_ROWS = 1;
    public static final int MAX_ROWS = 1000;

    private File() {}
  }

  public final class DB {
    public static final String name = "oups";

    public final class Connection {
      public static final String URL = "jdbc:tra-ta-ta";
      public static final String USER = "testUser";
      public static final String PASSWORD = "testPassword";

      private Connection() {}
    }

    private DB() {}
  }

  private Constants() {}
}

Niż na przykład używam Constants.DB.Connection.URLdo uzyskania stałej. Jak dla mnie wygląda bardziej „obiektowo”.

albus.ua
źródło
4
Ciekawe, ale nieporęczne. Dlaczego zamiast tego nie tworzyć stałych w klasie najbardziej z nimi powiązanej, jak zalecają inni? Na przykład, czy w kodzie DB gdzie indziej masz klasę bazową dla swoich połączeń? Np. „ConnectionBase”. Następnie możesz umieścić tam stałe. Każdy kod, który działa z połączeniami, prawdopodobnie już ma taki import, który może po prostu powiedzieć „ConnectionBase.URL” zamiast „Constants.DB.Connection.URL”.
ToolmakerSteve
3
@ToolmakerSteve Ale co z ogólnymi stałymi, których może używać wiele klas? na przykład style, adresy usług internetowych itp.?
Daniel Gomez Rico
Umieszczenie wszystkich stałych w jednej klasie ma jedną zaletę - utrzymanie. Zawsze dokładnie wiesz, gdzie znaleźć stałe. Nie twierdzę, że dzięki temu ta technika jest lepsza, mam tylko jedną zaletę. To, co zrobił @ albus.ua, skategoryzowało jego stałe, co jest całkiem dobrym pomysłem, szczególnie jeśli klasa stałych zawiera wiele wielu stałych wartości. Ta technika pomoże utrzymać klasę w zarządzaniu i pomoże lepiej opisać cel stałej.
Nelda.techspiress
17

Tworzenie statycznych stałych końcowych w oddzielnej klasie może sprawić kłopoty. Kompilator Java faktycznie to zoptymalizuje i umieści rzeczywistą wartość stałej w dowolnej klasie, która się do niej odwołuje.

Jeśli później zmienisz klasę „Stałe” i nie dokonasz trudnej ponownej kompilacji na innych klasach, które odwołują się do tej klasy, skończysz z użyciem kombinacji starych i nowych wartości.

Zamiast myśleć o nich jako o stałych, pomyśl o nich jako o parametrach konfiguracyjnych i stwórz klasę do zarządzania nimi. Niech wartości nie będą ostateczne, a nawet rozważ użycie getterów. W przyszłości, gdy ustalisz, że niektóre z tych parametrów powinny być konfigurowane przez użytkownika lub administratora, będzie to o wiele łatwiejsze.

Dzień Kevina
źródło
+1 za to doskonałe zastrzeżenie. (Jeśli nie możesz zagwarantować, że jest to stała stała, rozważ zamiast tego getter, jak wspomina big_peanut_horse.) To samo dotyczy const w C #, przy okazji: msdn.microsoft.com/en-us/library/e6w8fe1b.aspx
Jon Coombs
13

Najczęstszym błędem, jaki możesz popełnić, jest utworzenie globalnie dostępnej klasy o nazwie ogólnej, takiej jak Constants. To po prostu jest zaśmiecone śmieciami i tracisz wszelką zdolność do określenia, która część twojego systemu używa tych stałych.

Zamiast tego stałe powinny przejść do klasy, która je „posiada”. Czy masz stałą o nazwie TIMEOUT? Prawdopodobnie powinien przejść do klasy Communications () lub Connection (). MAX_BAD_LOGINS_PER_HOUR? Wchodzi w User (). I tak dalej i tak dalej.

Innym możliwym zastosowaniem są pliki .properties Java, gdy „stałe” można zdefiniować w czasie wykonywania, ale nie można ich łatwo zmienić. Możesz spakować je w pliku .jars i odwołać do nich za pomocą Class resourceLoader.

Yann Ramin
źródło
I oczywiście, nigdy nie chciałbyś mieć dostępu do stałej z więcej niż jednej klasy lub uniknąć bałaganu na szczycie klasy.
orbfish
6

To jest właściwa droga.

Zasadniczo stałe nie są przechowywane w osobnych klasach „Stałe”, ponieważ nie można ich wykryć. Jeśli stała jest istotna dla bieżącej klasy, utrzymanie jej tam pomaga następnemu deweloperowi.

Jason Cohen
źródło
5

Co z wyliczeniem?

Sébastien D.
źródło
5

Wolę używać getterów niż stałych. Te pobierające mogą zwracać stałe wartości, np. public int getMaxConnections() {return 10;}Ale wszystko, co potrzebuje stałej, przejdzie przez pobierający.

Jedną z korzyści jest to, że jeśli twój program przerośnie stałą - okaże się, że musi być konfigurowalny - możesz po prostu zmienić sposób, w jaki getter zwraca stałą.

Inną zaletą jest to, że aby zmodyfikować stałą, nie trzeba przekompilować wszystkiego, co z niej korzysta. Gdy odwołujesz się do statycznego pola końcowego, wartość tej stałej jest kompilowana do dowolnego kodu bajtowego, który się do niego odwołuje.

duży koń orzechowy
źródło
5
Dobrze skompilowana klasa odwołań nie jest w XXI wieku ciężarem. I nigdy nie powinieneś używać modelu akcesor / mutator (getter / setter) do celów innych niż uzyskiwanie dostępu i mutowanie zmiennych składowych. Stałe są pojęciowo przeznaczone do bycia bezpośrednimi w przyrodzie, podczas gdy getter / setters mają (oba) zarządzać stanem . Poza tym pytasz tylko o zamieszanie: ludzie nie oczekują, że getter da zwykłą stałą.
5

Zgadzam się, że korzystanie z interfejsu nie jest dobrym rozwiązaniem. Unikanie tego wzoru ma nawet swój własny przedmiot (# 18) w Efektywnej Javie Blocha .

Argumentem, który Bloch wysuwa przeciwko stałemu wzorcowi interfejsu jest to, że użycie stałych jest szczegółem implementacji, ale implementacja interfejsu do ich użycia ujawnia ten szczegół implementacji w eksportowanym interfejsie API.

The public|private static final TYPE NAME = VALUE;Wzór jest dobrym sposobem deklarowania stałej. Osobiście uważam, że lepiej unikać tworzenia osobnej klasy, w której zmieściłyby się wszystkie twoje stałe, ale nigdy nie widziałem powodu, aby tego nie robić, oprócz osobistych preferencji i stylu.

Jeśli twoje stałe mogą być dobrze modelowane jako wyliczenie, rozważ wyliczenie strukturę dostępną w wersji 1.5 lub nowszej.

Jeśli używasz wersji wcześniejszej niż 1.5, nadal możesz pobierać bezpieczne wyliczenia przy użyciu normalnych klas Java. (Zobacz tę stronę ).

Rob Dickerson
źródło
Niektóre stałe mogą być użyte do wywołania API. Na przykład zobacz interfejs org.springframework.transaction.TransactionDefinition. Ma listę stałych, takich jak int PROPAGATION_REQUIRED = 0;
borjab
Wiem, że to stare, ale link do Skutecznej Javy Blocha jest zepsuty. Czy możesz podać inne lub inne odniesienie potwierdzające, że „korzystanie z interfejsu nie jest właściwą drogą”, proszę?
Nelda.techspiress
4

W oparciu o powyższe komentarze uważam, że jest to dobre podejście do zmiany staromodnej globalnej klasy stałej (zawierającej publiczne statyczne zmienne końcowe) na jej ekwiwalentny odpowiednik w następujący sposób:

public class Constants {

    private Constants() {
        throw new AssertionError();
    }

    public interface ConstantType {}

    public enum StringConstant implements ConstantType {
        DB_HOST("localhost");
        // other String constants come here

        private String value;
        private StringConstant(String value) {
            this.value = value;
        }
        public String value() {
            return value;
        }
    }

    public enum IntConstant implements ConstantType {
        DB_PORT(3128), 
        MAX_PAGE_SIZE(100);
        // other int constants come here

        private int value;
        private IntConstant(int value) {
            this.value = value;
        }
        public int value() {
            return value;
        }
    }

    public enum SimpleConstant implements ConstantType {
        STATE_INIT,
        STATE_START,
        STATE_END;
    }

}

Więc mogę odnieść je do:

Constants.StringConstant.DB_HOST
Lorand Bendig
źródło
4
Dlaczego? Jak to jest poprawa? Każde odwołanie jest teraz uciążliwe (Constants.StringConstant.whokolwiek). IMHO, idziesz tutaj wyboistą drogą.
ToolmakerSteve
3

Dobry projekt obiektowy nie powinien wymagać wielu publicznie dostępnych stałych. Większość stałych powinna być zamknięta w klasie, która potrzebuje ich do wykonania swojej pracy.

Bradley Harris
źródło
1
Lub wstrzyknięty do tej klasy za pomocą konstruktora.
WW.
2

Odpowiedź na to pytanie jest pewna. Na początek, stałe w java są na ogół deklarowane jako publiczne, statyczne i końcowe. Oto powody:

public, so that they are accessible from everywhere
static, so that they can be accessed without any instance. Since they are constants it
  makes little sense to duplicate them for every object.
final, since they should not be allowed to change

Nigdy nie użyłbym interfejsu dla akcesorium / obiektu CONSTANTS po prostu dlatego, że ogólnie oczekuje się, że interfejsy zostaną zaimplementowane. Czy nie wyglądałoby to śmiesznie:

String myConstant = IMyInterface.CONSTANTX;

Zamiast tego wybrałbym kilka różnych sposobów, opartych na drobnych kompromisach, a więc zależy to od tego, czego potrzebujesz:

1.  Use a regular enum with a default/private constructor. Most people would define 
     constants this way, IMHO.
  - drawback: cannot effectively Javadoc each constant member
  - advantage: var members are implicitly public, static, and final
  - advantage: type-safe
  - provides "a limited constructor" in a special way that only takes args which match
     predefined 'public static final' keys, thus limiting what you can pass to the
     constructor

2.  Use a altered enum WITHOUT a constructor, having all variables defined with 
     prefixed 'public static final' .
  - looks funny just having a floating semi-colon in the code
  - advantage: you can JavaDoc each variable with an explanation
  - drawback: you still have to put explicit 'public static final' before each variable
  - drawback: not type-safe
  - no 'limited constructor'

3.  Use a Class with a private constructor:
  - advantage: you can JavaDoc each variable with an explanation
  - drawback: you have to put explicit 'public static final' before each variable
  - you have the option of having a constructor to create an instance
     of the class if you want to provide additional functions related
     to your constants 
     (or just keep the constructor private)
  - drawback: not type-safe

4. Using interface:
  - advantage: you can JavaDoc each variable with an explanation
  - advantage: var members are implicitly 'public static final'
  - you are able to define default interface methods if you want to provide additional
     functions related to your constants (only if you implement the interface)
  - drawback: not type-safe
djangofan
źródło
2

Jaki jest najlepszy sposób na implementację stałych w Javie?

Jedno podejście, którego naprawdę powinniśmy unikać : używanie interfejsów do definiowania stałych.

Stworzenie interfejsu specjalnie do deklarowania stałych jest naprawdę najgorszą rzeczą: pokonuje powód, dla którego zaprojektowano interfejsy: definiowanie kontraktów metod.

Nawet jeśli interfejs już istnieje, aby zaspokoić określoną potrzebę, deklarowanie stałych w nich naprawdę nie ma sensu, ponieważ stałe nie powinny stanowić części interfejsu API i kontraktu udostępnianego klasom klientów.


Aby uprościć, mamy zasadniczo 4 prawidłowe podejścia .

Z static final String/Integerpolem:

  • 1) użycie klasy, która deklaruje stałe wewnątrz, ale nie tylko.
  • 1 wariant), tworząc klasę dedykowaną tylko do deklarowania stałych.

Z Java 5 enum:

  • 2) deklarowanie wyliczenia w pokrewnej klasie celu (takiej jak klasa zagnieżdżona).
  • 2 wariant) tworzenie wyliczenia jako samodzielnej klasy (tak zdefiniowanej we własnym pliku klasy).

TLDR: Jaki jest najlepszy sposób i gdzie zlokalizować stałe?

W większości przypadków sposób wyliczania jest prawdopodobnie lepszy niż static final String/Integersposób i osobiście uważam, że static final String/Integersposób ten należy stosować tylko wtedy, gdy mamy uzasadnione powody, aby nie używać wyliczeń.
Jeśli chodzi o to, gdzie powinniśmy zadeklarować wartości stałe, chodzi o sprawdzenie, czy istnieje jedna istniejąca klasa posiadająca określoną i silną spójność funkcjonalną o stałych wartościach. Jeśli znajdziemy taką klasę, powinniśmy użyć jej jako uchwytu stałych . W przeciwnym razie stała nie powinna być powiązana z żadną konkretną klasą.


static final String/ static final Integerversusenum

Wykorzystanie wyliczeń jest naprawdę sposobem na zdecydowane rozważenie.
Wyliczenia mają wielką przewagę nad Stringlub Integerstałe pole.
Ustawiają silniejsze ograniczenie kompilacji. Jeśli zdefiniujesz metodę przyjmującą wyliczenie jako parametr, możesz przekazać tylko wartość wyliczoną zdefiniowaną w klasie wyliczeniowej (lub null).
Za pomocą String i Integer możesz zastąpić je dowolnymi wartościami zgodnego typu, a kompilacja będzie w porządku, nawet jeśli wartość nie jest zdefiniowaną stałą w polach static final String/ static final Integer.

Na przykład poniżej dwóch stałych zdefiniowanych w klasie jako static final Stringpola:

public class MyClass{

   public static final String ONE_CONSTANT = "value";
   public static final String ANOTHER_CONSTANT = "other value";
   . . .
}

Oto metoda, która spodziewa się mieć jedną z tych stałych jako parametr:

public void process(String constantExpected){
    ...    
}

Możesz go wywołać w ten sposób:

process(MyClass.ONE_CONSTANT);

lub

process(MyClass.ANOTHER_CONSTANT);

Ale żadne ograniczenie kompilacji nie uniemożliwia wywołania go w ten sposób:

process("a not defined constant value");

Błąd wystąpiłby tylko w środowisku wykonawczym i tylko wtedy, gdy sprawdzana jest przekazywana wartość.

W przypadku wyliczania sprawdzania nie są wymagane, ponieważ klient może przekazać tylko wartość wyliczenia w parametrze wyliczenia.

Na przykład tutaj dwie wartości zdefiniowane w klasie enum (tak stałej po wyjęciu z pudełka):

public enum MyEnum {

    ONE_CONSTANT("value"), ANOTHER_CONSTANT(" another value");

    private String value;

    MyEnum(String value) {
       this.value = value;
    }
         ...
}

Oto metoda, która oczekuje, że jedną z tych wartości wyliczeniowych będzie parametr:

public void process(MyEnum myEnum){
    ...    
}

Możesz go wywołać w ten sposób:

process(MyEnum.ONE_CONSTANT);

lub

process(MyEnum.ANOTHER_CONSTANT);

Ale kompilacja nigdy nie pozwoli ci na wywołanie jej w ten sposób:

process("a not defined constant value");

Gdzie powinniśmy zadeklarować stałe?

Jeśli aplikacja zawiera jedną istniejącą klasę, która posiada określoną i silną spójność funkcjonalną o stałych wartościach, 1) i 2) wydają się bardziej intuicyjne.
Zasadniczo ułatwia stosowanie stałych, jeśli są one zadeklarowane w głównej klasie, która nimi manipuluje lub ma nazwę bardzo naturalną, aby zgadywać, że znajdziemy ją w środku.

Na przykład w bibliotece JDK wartości wykładnicze i stałe pi są deklarowane w klasie, która deklaruje nie tylko stałe deklaracje ( java.lang.Math).

   public final class Math {
          ...
       public static final double E = 2.7182818284590452354;
       public static final double PI = 3.14159265358979323846;
         ...
   }

Klienci korzystający z funkcji matematycznych często polegają na Mathklasie. Mogą więc łatwo znaleźć stałe i mogą również pamiętać, gdzie Ei PIsą zdefiniowane w bardzo naturalny sposób.

Jeśli twoja aplikacja nie zawiera istniejącej klasy, która ma bardzo specyficzną i silną spójność funkcjonalną ze stałymi wartościami, wariant 1) i wariant 2) wydają się bardziej intuicyjne.
Zasadniczo nie ułatwia użycia stałych, jeśli są one zadeklarowane w jednej klasie, która nimi manipuluje, podczas gdy mamy również 3 lub 4 inne klasy, które manipulują nimi tak bardzo, i żadna z tych klas nie wydaje się bardziej naturalna niż inne stałe wartości hosta.
W tym przypadku sensowne jest zdefiniowanie niestandardowej klasy do przechowywania tylko stałych wartości.
Na przykład w bibliotece JDK java.util.concurrent.TimeUnitwyliczenie nie jest deklarowane w konkretnej klasie, ponieważ tak naprawdę nie ma jednej i tylko jednej klasy JDK, która wydaje się być najbardziej intuicyjna do przechowywania:

public enum TimeUnit {
    NANOSECONDS {
      .....
    },
    MICROSECONDS {
      .....
    },
    MILLISECONDS {
      .....
    },
    SECONDS {
      .....
    },
      .....
}      

Wiele klas zadeklarowane w java.util.concurrentużyciu im: BlockingQueue, ArrayBlockingQueue<E>, CompletableFuture, ExecutorService, ... i tak naprawdę nikt z nich wydaje się bardziej odpowiednie do przechowywania wyliczenia.

davidxxx
źródło
1

Stałą dowolnego typu można zadeklarować, tworząc niezmienną właściwość w obrębie klasy (czyli zmienną składową z finalmodyfikatorem). Zazwyczaj dostarczane są również modyfikatory statici public.

public class OfficePrinter {
    public static final String STATE = "Ready";  
}

Istnieje wiele aplikacji, w których wartość stałej wskazuje wybór spośród n-krotki (np. Wyliczenia ) wyborów. W naszym przykładzie możemy wybrać zdefiniowanie typu wyliczeniowego, który ograniczy możliwe przypisane wartości (tj. Lepsze bezpieczeństwo typu ):

public class OfficePrinter {
    public enum PrinterState { Ready, PCLoadLetter, OutOfToner, Offline };
    public static final PrinterState STATE = PrinterState.Ready;
}
Ryan Delucchi
źródło
1

Pojedyncza, ogólna klasa stałych jest złym pomysłem. Stałe powinny być zgrupowane razem z klasą, z którą są najbardziej logicznie powiązane.

Zamiast używać dowolnego rodzaju zmiennych (szczególnie wyliczeń), sugerowałbym użycie metod. Utwórz metodę o tej samej nazwie co zmienna i niech zwróci wartość przypisaną zmiennej. Teraz usuń zmienną i zastąp wszystkie odniesienia do niej wywołaniami do właśnie utworzonej metody. Jeśli uważasz, że stała jest na tyle ogólna, że ​​nie powinieneś tworzyć instancji klasy tylko po to, aby z niej korzystać, a następnie ustaw stałą metodę na metodę klasy.


źródło
1

FWIW, wartość limitu czasu w sekundach powinna być prawdopodobnie ustawieniem konfiguracyjnym (wczytywanym z pliku właściwości lub poprzez wstrzyknięcie jak wiosną), a nie stałą.

Tim Howland
źródło
1

Jaka jest różnica

1.

public interface MyGlobalConstants {
    public static final int TIMEOUT_IN_SECS = 25;
}

2)

public class MyGlobalConstants {
    private MyGlobalConstants () {} // Prevents instantiation
    public static final int TIMEOUT_IN_SECS = 25;
}

i MyGlobalConstants.TIMEOUT_IN_SECSgdziekolwiek potrzebujemy tej stałej. Myślę, że oba są takie same.

chandrayya
źródło
1
Wydaje się, że jest to zasadniczo komentarz w odpowiedzi na udzieloną przez bincob odpowiedź. Myślę, że zachowują się bardzo podobnie, ale bincob miał na myśli to, że w żaden sposób nie definiują interfejsu. Sugerowano, aby dodać stałe do prawdziwych klas, a nie tworzyć szkieletową klasę MyGlobalConstants. (Chociaż czasami ma to sens; użyj „klasy statycznej”, mając stałe statyczne i prywatny konstruktor, aby zapobiec tworzeniu instancji; zobacz java.lang.math.) Rozważ użycie enum.
Jon Coombs,
Również umieszczenie „końcowego” w deklaracji klasy zapobiegnie podklasowaniu. (W języku C # można zrobić „statyczny”, co oznacza „ostateczny abstrakt”, więc nie ma potrzeby jawnego prywatnego konstruktora.)
Jon Coombs
Tak, @JonCoombs, ale „końcowy” nie zapobiega bezpośredniej instancji. A Java nie zezwala na to, by zarówno ostateczne, jak i abstrakcyjne pojawiały się razem dla klas, stąd niekończący się prywatny konstruktor, który zapobiega zarówno tworzeniu instancji, jak i podklasowaniu. Nie mam pojęcia, dlaczego „ostateczny abstrakt” jest niedozwolony, inaczej niż na pierwszy rzut oka wydaje się sprzeczny w jego brzmieniu: „nie można podklasować, ale ta klasa ma być podklasą”.
0

Nie nazwałbym tej samej klasy (poza obudową) co stałej ... Miałbym co najmniej jedną klasę „Ustawień”, „Wartości” lub „Stałych”, w których żyłyby wszystkie stałe. Jeśli mam ich dużą liczbę, pogrupuję je w logiczne klasy stałe (UserSettings, AppSettings itp.)

Joel Martinez
źródło
Posiadanie zajęć o nazwie Constants było tym, co planowałem zrobić, to był tylko mały przykład, który znalazłem.
mk.
0

Aby pójść o krok dalej, możesz umieścić globalnie używane stałe w interfejsie, aby mogły być używane w całym systemie. Na przykład

public interface MyGlobalConstants {
    public static final int TIMEOUT_IN_SECS = 25;
}

Ale nie wdrażaj go. Po prostu odwołaj się do nich bezpośrednio w kodzie za pomocą w pełni kwalifikowanej nazwy klasy.

Andrew Harmel-Law
źródło
Chodzi o to, aby zadeklarować je w interfejsie (a nie zaimplementować go), że można pominąć „publiczny statyczny finał”.
Tom Hawtin - tackline
9
Interfejsy służą do definiowania kontraktu behawioralnego, a nie wygodnego mechanizmu przechowywania stałych.
John Topley,
@JohnTopley Tak, ale działa. ;)
trusktr
0

Dla stałych Enum jest lepszym wyborem IMHO. Oto przykład

klasa publiczna myClass {

public enum myEnum {
    Option1("String1", 2), 
    Option2("String2", 2) 
    ;
    String str;
            int i;

            myEnum(String str1, int i1) { this.str = str1 ; this.i1 = i }


}
mmansoor
źródło
0

Jednym ze sposobów, w jaki to robię, jest utworzenie klasy „Global” ze stałymi wartościami i wykonanie importu statycznego do klas, które potrzebują dostępu do stałej.

Javamann
źródło
0

static finalzgodnie z moimi preferencjami, użyłbym tylko, enumjeśli przedmiot był rzeczywiście wymienny.

wulfgarpro
źródło
0

używam static final do deklarowania stałych i używam notacji nazewniczej ALL_CAPS. Widziałem sporo rzeczywistych przypadków, w których wszystkie stałe są powiązane w jeden interfejs. Kilka postów słusznie uznało to za złą praktykę, przede wszystkim dlatego, że nie do tego służy interfejs. Interfejs powinien egzekwować kontrakt i nie powinien być miejscem do umieszczania niepowiązanych stałych. Złożenie go razem w klasę, której nie można utworzyć również za pośrednictwem prywatnego konstruktora, jest w porządku, jeśli stała semantyka nie należy do konkretnej klasy ( es). Zawsze umieszczam stałą w klasie, z którą jest najbardziej związana, ponieważ ma to sens i jest łatwe do utrzymania.

Wyliczenia są dobrym wyborem do reprezentowania zakresu wartości, ale jeśli przechowujesz autonomiczne stałe z naciskiem na wartość bezwzględną (np. TIMEOUT = 100 ms), możesz po prostu wybrać static finalpodejście.

bincob
źródło
0

Zgadzam się z tym, co większość mówi, najlepiej używać wyliczeń, mając do czynienia z kolekcją stałych. Jeśli jednak programujesz w Androidzie, istnieje lepsze rozwiązanie: Adnotacja IntDef .

@Retention(SOURCE)
@IntDef({NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST,NAVIGATION_MODE_TABS})
public @interface NavigationMode {}
public static final int NAVIGATION_MODE_STANDARD = 0;
public static final int NAVIGATION_MODE_LIST = 1;
public static final int NAVIGATION_MODE_TABS = 2;
...
public abstract void setNavigationMode(@NavigationMode int mode);
@NavigationMode
public abstract int getNavigationMode();

Adnotacja IntDef przewyższa wyliczenia w jeden prosty sposób, zajmuje znacznie mniej miejsca, ponieważ jest po prostu znacznikiem czasu kompilacji. To nie jest klasa, ani nie ma właściwości automatycznej konwersji łańcucha.

Quinn Turner
źródło
Chociaż zgadzam się z najlepszą praktyką nieużywania interfejsu w samej Javie i unikania wyliczania w Androidzie, ta zamiana w Androidzie działa tylko wtedy, gdy używasz niewielkiej liczby pól. Jest to znaczna oszczędność pamięci, ale może prowadzić do wzdęć, ponieważ jesteś interfejsem dla pola w mieszanym wyliczeniu. Na przykład, jeśli mam mieszane wyliczanie, które definiuje to, co obiekt bierze do swojego konstruktora, nie mogę zapisać niczego przy takim podejściu i wracam do stałych bezpiecznych nietypowych, ponieważ w Androidzie nie chcesz zbyt wielu okresów klas / interfejsów.
Droid Teahouse
0

Cytowanie Joshua Blocha bez zrozumienia podstawowego fundamentalnego zerowego fundamentu jest ZŁYM przyzwyczajeniem i strasznie NIESAMOWITEJ praktyką .

Nic też nie czytałem Joshua Bloch, więc też

  • on jest okropnym programistą
  • lub ludzie, których do tej pory go cytuję (Joshua to imię chłopca, który, jak przypuszczam), po prostu wykorzystują jego materiał jako religijne skrypty, aby uzasadnić swoje religijne odpusty.

Podobnie jak w fundamentalizmie biblijnym, wszystkie prawa biblijne można podsumować

  • Kochajcie Podstawową Tożsamość całym swoim sercem i całym umysłem
  • Kochaj swojego bliźniego jak siebie samego

i podobnie można podsumować fundamentalizm inżynierii oprogramowania

  • poświęć się podstawom zerowym z całą siłą i umysłem programowania
  • i poświęcajcie się doskonałości innych programistów, tak jak dla siebie.

Również wśród biblijnych kręgów fundamentalistycznych wyciąga się silny i rozsądny wniosek

  • Najpierw pokochaj siebie. Ponieważ jeśli nie bardzo się kochasz, pojęcie „kochaj swojego bliźniego jak siebie samego” nie ma większego znaczenia, ponieważ „jak bardzo siebie kochasz” jest linią odniesienia, powyżej której kochałbyś innych.

Podobnie, jeśli nie szanujesz siebie jako programisty i po prostu akceptujesz wypowiedzi i proroctwa jakiegoś programistycznego guru-natha BEZ kwestionowania podstaw, twoje cytaty i poleganie na Joshua Bloch (i tym podobnych) są bez znaczenia. Dlatego w rzeczywistości nie miałbyś szacunku dla innych programistów.

Podstawowe prawa programowania oprogramowania

  • lenistwo jest zaletą dobrego programisty
  • masz uczynić swoje życie programistycznym tak łatwym, leniwym, a zatem tak efektywnym, jak to możliwe
  • masz za zadanie uczynić konsekwencje i wnętrzności twojego programowania tak łatwymi, leniwymi, a zatem jak najbardziej efektywnymi dla twoich sąsiadów-programistów, którzy pracują z tobą i podnoszą twoje wnętrzności programistyczne.

Stałe wzorców interfejsów to zły nawyk ???

Na podstawie jakich zasad fundamentalnie skutecznego i odpowiedzialnego programowania obejmuje ten religijny edykt?

Wystarczy przeczytać artykuł w Wikipedii na temat stałych wzorców interfejsów ( https://en.wikipedia.org/wiki/Constant_interface ), a głupie usprawiedliwienie to w stosunku do stałych wzorców interfejsu.

  • Whatif-No IDE? Kto na ziemi jako programista nie używałby IDE? Większość z nas to programiści, którzy wolą nie musieć dowodzić posiadania macho-estetycznego surwiwalizmu poprzez unikanie użycia IDE.

    • Ponadto - poczekaj na drugich zwolenników programowania mikro-funkcjonalnego, jako na środek niepotrzebny IDE. Poczekaj, aż przeczytasz moje wyjaśnienie dotyczące normalizacji modelu danych.
  • Czy zanieczyszcza przestrzeń nazw zmiennymi nieużywanymi w bieżącym zakresie? Mogą to być zwolennicy tej opinii

    • nie zdają sobie sprawy z normalizacji modelu danych i jej potrzeby
  • Używanie interfejsów do wymuszania stałych jest nadużywaniem interfejsów. Zwolennicy takich mają zły nawyk

    • nie widząc, że „stałe” należy traktować jako kontrakt. Interfejsy służą do egzekwowania lub projekcji zgodności z umową.
  • Konwersja interfejsów na zaimplementowane klasy w przyszłości jest trudna, jeśli nie niemożliwa. Hah .... hmmm ... ???

    • Dlaczego miałbyś chcieć angażować się w taki schemat programowania, jak trwałe utrzymanie? WIĘCEJ, po co poświęcać się tak WSPANIAŁEMU i złemu nawykowi programowania?

Niezależnie od wymówek, NIE MA ŻADNEGO WYMAGANIA, jeśli chodzi o FUNDAMENTALNIE SKUTECZNĄ inżynierię oprogramowania do delegitymizacji lub ogólnie zniechęcania do stosowania stałych interfejsu.

Nie ma znaczenia, jakie były pierwotne zamiary i stany mentalne ojców założycieli, którzy opracowali Konstytucję Stanów Zjednoczonych. Moglibyśmy omówić pierwotne intencje ojców założycieli, ale obchodzą mnie tylko pisemne oświadczenia Konstytucji Stanów Zjednoczonych. I obowiązkiem każdego obywatela USA jest wykorzystanie pisemnego fundamentalizmu literackiego, a nie niepisanych założeń założycielskich, konstytucji Stanów Zjednoczonych.

Podobnie nie obchodzi mnie, jakie „oryginalne” intencje twórców platformy Java i języka programowania miały dla interfejsu. Zależy mi na efektywnych funkcjach, które zapewnia specyfikacja Java, i zamierzam w pełni wykorzystać te funkcje, aby pomóc mi w spełnieniu podstawowych praw odpowiedzialnego programowania. Nie obchodzi mnie, czy jestem postrzegany jako „naruszający intencję interfejsów”. Nie obchodzi mnie, co Gosling lub ktoś Bloch mówi o „właściwym sposobie korzystania z Javy”, chyba że to, co mówią, nie narusza mojej potrzeby SKUTECZNEGO wypełniania podstaw.

Podstawą jest normalizacja modelu danych

Nie ma znaczenia, w jaki sposób model danych jest hostowany lub przesyłany. Bez względu na to, czy używasz interfejsów, wyliczeń, czy cokolwiek innego, relacyjnego lub bez SQL, jeśli nie rozumiesz potrzeby i procesu normalizacji modelu danych.

Najpierw musimy zdefiniować i znormalizować model danych zestawu procesów. A kiedy mamy spójny model danych, TYLKO wtedy możemy wykorzystać przepływ procesów jego komponentów do zdefiniowania zachowania funkcjonalnego i proces blokuje pole lub dziedzinę aplikacji. I tylko wtedy możemy zdefiniować API każdego procesu funkcjonalnego.

Nawet aspekty normalizacji danych zaproponowane przez EF Codda są obecnie poważnie kwestionowane i poważnie kwestionowane. np. jego oświadczenie w sprawie 1NF zostało skrytykowane jako dwuznaczne, niedopasowane i nadmiernie uproszczone, podobnie jak reszta jego oświadczeń, szczególnie w związku z pojawieniem się nowoczesnych usług danych, technologii repo i transmisji. IMO, oświadczenia EF Codda powinny zostać całkowicie porzucone i należy opracować nowy zestaw bardziej matematycznie wiarygodnych stwierdzeń.

Rażącą wadą EF Codda i przyczyną jego niedopasowania do skutecznego zrozumienia przez człowieka jest jego przekonanie, że ludzko postrzegalne wielowymiarowe, zmienne wymiary można skutecznie postrzegać poprzez zestaw fragmentarycznych dwuwymiarowych mapowań.

Podstawy normalizacji danych

Czego EF Codd nie wyraził.

W ramach każdego spójnego modelu danych są to sekwencyjne stopniowane stopniowanie spójności modelu danych do osiągnięcia.

  1. Jedność i tożsamość instancji danych.
    • zaprojektować ziarnistość każdego składnika danych, przy czym ich ziarnistość jest na poziomie, na którym każde wystąpienie składnika można jednoznacznie zidentyfikować i pobrać.
    • brak aliasingu instancji. tzn. nie ma żadnych środków, dzięki którym identyfikacja wytworzy więcej niż jedną instancję komponentu.
  2. Brak przesłuchu instancji. Nie istnieje konieczność użycia jednego lub więcej innych wystąpień komponentu, aby przyczynić się do identyfikacji wystąpienia komponentu.
  3. Jedność i tożsamość komponentów / wymiarów danych.
    • Obecność usuwania aliasingu komponentów. Musi istnieć jedna definicja, w której można jednoznacznie zidentyfikować komponent / wymiar. Która jest podstawową definicją komponentu;
    • gdzie podstawowa definicja nie spowoduje ujawnienia pod wymiarów lub elementów składowych, które nie są częścią zamierzonego elementu;
  4. Unikalne środki do usuwania składników. Musi istnieć jedna i tylko jedna taka definicja usuwania aliasingu dla komponentu.
  5. Istnieje jeden i tylko jeden interfejs lub umowa definicji służąca do identyfikacji komponentu macierzystego w hierarchicznej relacji komponentów.
  6. Brak przesłuchu komponentu. Nie ma potrzeby używania elementu innego komponentu w celu przyczynienia się do ostatecznej identyfikacji komponentu.
    • W takim związku rodzic-dziecko definicja identyfikująca rodzica nie może zależeć od części zestawu elementów składowych dziecka. Element członkowski tożsamości rodzica musi być kompletną tożsamością dziecka bez odwoływania się do jednego lub wszystkich dzieci dziecka.
  7. Zapobieganie dwumodalnym lub multimodalnym wyglądom modelu danych.
    • Gdy istnieją dwie kandydujące definicje komponentu, jest to oczywisty znak, że istnieją dwa różne modele danych pomieszane jako jeden. Oznacza to, że występuje niespójność na poziomie modelu danych lub na poziomie pola.
    • Obszar zastosowań musi wykorzystywać spójny jeden i tylko jeden model danych.
  8. Wykryj i zidentyfikuj mutację komponentu. O ile nie wykonałeś statystycznej analizy składowej ogromnych danych, prawdopodobnie nie widzisz ani nie widzisz potrzeby leczenia mutacji składników.
    • W modelu danych niektóre jego komponenty mogą mutować cyklicznie lub stopniowo.
    • Tryb może być rotacją pręta lub rotacją transpozycji.
    • Mutacja rotacji elementów mogłaby polegać na wyraźnym zamianie komponentów potomnych między komponentami. Lub gdzie należałoby zdefiniować zupełnie nowe komponenty.
    • Mutacja transpozycyjna przejawiałaby się jako mutacja elementu wymiarowego w atrybut, i odwrotnie.
    • Każdy cykl mutacji musi być zidentyfikowany jako odrębny modal danych.
  9. Wersjonuj każdą mutację. Tak, że możesz wyciągnąć poprzednią wersję modelu danych, gdy być może zajdzie potrzeba leczenia 8-letniej mutacji modelu danych.

W polu lub siatce międzyobsługowych aplikacji składowych musi istnieć jeden i tylko jeden spójny model danych lub istnieje sposób na identyfikację modelu / wersji danych.

Czy nadal pytamy, czy moglibyśmy użyć stałych interfejsu? Naprawdę

Zagadnienia związane z normalizacją danych są bardziej istotne niż to przyziemne pytanie. JEŚLI nie rozwiążesz tych problemów, zamieszanie, które Twoim zdaniem powodują stałe interfejsu, jest względnie niczym. Zilch.

Na podstawie normalizacji modelu danych określa się komponenty jako zmienne, właściwości, stałe interfejsu kontraktu.

Następnie określasz, które z nich mają zostać wprowadzone do wartości, umieszczenie konfiguracji właściwości, interfejsy, końcowe łańcuchy itp.

Jeśli musisz użyć wymówki, aby łatwiej zlokalizować komponent pod kątem stałych interfejsu, oznacza to, że masz zły nawyk nie praktykowania normalizacji modelu danych.

Być może chcesz skompilować model danych w wersji vcs. Że możesz wyciągnąć wyraźnie identyfikowalną wersję modelu danych.

Wartości zdefiniowane w interfejsach są całkowicie pewne, że nie można ich modyfikować. I możliwe do udostępnienia. Po co ładować zestaw końcowych ciągów do swojej klasy z innej klasy, gdy wszystko, czego potrzebujesz, to zestaw stałych?

Dlaczego więc nie opublikować umowy na model danych? Mam na myśli to, że jeśli potrafisz to spójnie zarządzać i normalizować, dlaczego nie? ...

public interface CustomerService {
  public interface Label{
    char AssignmentCharacter = ':';
    public interface Address{
      String Street = "Street";
      String Unit= "Unit/Suite";
      String Municipal = "City";
      String County = "County";
      String Provincial = "State";
      String PostalCode = "Zip"
    }

    public interface Person {
      public interface NameParts{
        String Given = "First/Given name"
        String Auxiliary = "Middle initial"
        String Family = "Last name"
      }
    }
  }
}

Teraz mogę odwoływać się do zakontraktowanych etykiet moich aplikacji w następujący sposób

CustomerService.Label.Address.Street
CustomerService.Label.Person.NameParts.Family

To myli zawartość pliku jar? Jako programista Java nie dbam o strukturę słoika.

Czy to komplikuje zamianę środowiska uruchomieniowego motywowaną osgi? Osgi jest niezwykle skutecznym środkiem pozwalającym programistom na kontynuowanie złych nawyków. Są lepsze alternatywy niż osgi.

A dlaczego nie to? Nie ma wycieku prywatnych stałych do opublikowanej umowy. Wszystkie prywatne stałe powinny być zgrupowane w prywatny interfejs o nazwie „Stałe”, ponieważ nie chcę wyszukiwać stałych i jestem zbyt leniwy, aby wielokrotnie wpisywać „prywatny końcowy ciąg”.

public class PurchaseRequest {
  private interface Constants{
    String INTERESTINGName = "Interesting Name";
    String OFFICIALLanguage = "Official Language"
    int MAXNames = 9;
  }
}

Być może nawet to:

public interface PurchaseOrderConstants {
  public interface Properties{
    default String InterestingName(){
       return something();
    }
    String OFFICIALLanguage = "Official Language"
    int MAXNames = 9;
  }
}

Jedyny problem ze stałymi interfejsami, który warto rozważyć, to kiedy interfejs jest implementowany.

To nie jest „pierwotna intencja” interfejsów? Tak, jakbym dbał o „pierwotną intencję” ojców założycieli w tworzeniu Konstytucji Stanów Zjednoczonych, a nie o to, jak Sąd Najwyższy interpretowałby pisane listy Konstytucji USA?

W końcu mieszkam w krainie wolnych, dzikiej i ojczyźnie odważnych. Bądź odważny, bądź wolny, bądź dziki - skorzystaj z interfejsu. Jeśli moi koledzy programiści odmawiają użycia wydajnych i leniwych środków programowania, czy zgodnie ze złotą zasadą jestem zmuszony zmniejszyć wydajność programowania, aby dostosować się do ich? Być może powinienem, ale to nie jest idealna sytuacja.

Błogosławiony Geek
źródło