Jaki jest najlepszy sposób implementacji stałych w Javie? [zamknięte]

Widziałem takie przykłady:

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

I przypuszczałem, że mogę mieć klasę stałych do zawijania stałych, ogłaszając je static final. Nie znam praktycznie żadnej Javy i zastanawiam się, czy jest to najlepszy sposób na tworzenie stałych.

Author: jjnguy, 2008-09-15

28 answers

To jest całkowicie dopuszczalne, prawdopodobnie nawet standard.

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

Gdzie TYPE jest typem, {[3] } jest nazwą we wszystkich literach z podkreślnikami dla spacji, a VALUE jest wartością stałą;

Zdecydowanie zalecam nie umieszczanie stałych w ich własnych klasach lub interfejsach.

Na marginesie: zmienne, które są zadeklarowane jako ostateczne i zmienne mogą być nadal zmieniane; jednak zmienna nigdy nie może wskazywać na inny obiekt.

Dla przykład:

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

public static void main(String[] args){

    ORIGIN.x = 3;

}

To jest legalne i ORIGIN byłoby wtedy punktem na (3, 0).

 403
Author: jjnguy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-22 17:31:54

Zdecydowanie odradzam posiadanie jednej klasy stałych. Może się to wydawać dobrym pomysłem w tym czasie, ale kiedy deweloperzy odmawiają dokumentowania stałych, a klasa rozrasta się do ponad 500 stałych, które nie są ze sobą w ogóle powiązane (są związane z zupełnie różnymi aspektami aplikacji), to na ogół zamienia się w plik stałych, który jest całkowicie nieczytelny. Zamiast:

  • Jeśli masz dostęp do Java 5+, użyj enums, aby zdefiniować swoje konkretne stałe dla obszaru zastosowania. Wszystkie części obszaru zastosowania powinny odnosić się do wartości liczbowych, a nie do wartości stałych. Możesz zadeklarować enum podobne do tego, jak deklarujesz klasę. Enums są prawdopodobnie najbardziej (i prawdopodobnie tylko) użyteczną cechą Javy 5+.
  • Jeśli masz stałe, które są ważne tylko dla określonej klasy lub jednej z jej podklas, zadeklaruj je jako chronione lub publiczne i umieść je na najwyższej klasie w hierarchii. W ten sposób podklasy mogą dostęp do tych wartości stałych (a jeśli inne klasy mają do nich dostęp za pośrednictwem publicznej, stałe są ważne nie tylko dla konkretnej klasy...co oznacza, że zewnętrzne klasy używające tej stałej mogą być zbyt ściśle powiązane z klasą zawierającą stałą)
  • Jeśli masz interfejs o zdefiniowanym zachowaniu, ale zwracane wartości lub wartości argumentów powinny być konkretne, jest całkowicie akceptowalne definiowanie stałych w tym interfejsie, aby inne implementatory miały do nich dostęp. Unikaj jednak tworzenia interfejsu tylko po to, aby trzymać stałe: może on stać się tak samo zły jak Klasa stworzona tylko po to, aby trzymać stałe.
 235
Author: MetroidFan2002,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-15 19:51:44

To jest zła praktyka używać interfejsów tylko do przechowywania stałych (nazwany stały wzór interfejsu przez Josha Blocha). Oto co Josh radzi:

Jeśli stałe są silnie związane z istniejącej klasy lub interfejsu, ty należy dodać je do klasy lub interfejs. Na przykład, wszystkie pudełkowe klasy prymitywne numeryczne, takich jak Integer i Double, eksport Stałe MIN_VALUE i MAX_VALUE. Jeśli stałe najlepiej oglądać jako członkowie wyliczony Typ, ty należy je wyeksportować za pomocą enum Typ. W przeciwnym razie należy wyeksportować stałe z niestanowiącym Klasa użytkowa.

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;
}

O konwencji nazewnictwa:

Zgodnie z konwencją, takie pola mają nazwy składający się z wielkich liter, z słowa oddzielone podkreślnikami. On krytyczne, że pola te zawierają albo prymitywne wartości lub odniesienia do obiektów niezmiennych.

 120
Author: Marcio Aguiar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-02 00:20:07

W Effective Java (2nd edition) zaleca się używanie enums zamiast statycznych ints dla stałych.

Jest tu dobry writeup na enums w Javie: http://java.sun.com/j2se/1.5.0/docs/guide/language/enums.html

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

Więc kiedy należy używać enums?

Z odpowiedzią:

W każdej chwili potrzebny jest stały zbiór stałych

 36
Author: shelfoo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-29 07:16:36

Po prostu unikaj używania interfejsu:

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

public class NeddsConstant implements MyConstants {

}

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

 21
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-15 19:45:33

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.URL, Aby uzyskać stałą. Wygląda bardziej "obiektowo" jak dla mnie.

 19
Author: albus.ua,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-12 16:35:59

Tworzenie statycznych stałych końcowych w osobnej klasie może przysporzyć ci kłopotów. Kompilator Java faktycznie zoptymalizuje to 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 wykonasz twardej ponownej kompilacji na innych klasach, które odwołują się do tej klasy, skończysz z kombinacją starych i nowych wartości.

Zamiast myśleć o nich jako o stałych, pomyśl o nich jako o konfiguracji parametry i utworzyć 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 faktycznie powinny być konfigurowalne przez użytkownika lub administratora, będzie to znacznie łatwiejsze do zrobienia.

 17
Author: Kevin Day,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-16 03:36:05

Największym błędem, jaki możesz popełnić, jest stworzenie globalnie dostępnej klasy o nazwie generycznej, takiej jak stałe. To po prostu robi się zaśmiecone śmieciami i tracisz całą zdolność do dowiedzieć się, która część systemu używa tych stałych.

Zamiast tego stałe powinny trafić do klasy, która je "posiada". Czy masz stały limit czasu? Prawdopodobnie powinien trafić do klasy Communications () lub Connection (). MAX_BAD_LOGINS_PER_HOUR? Przechodzi do User (). I tak dalej i i tak dalej.

Innym możliwym zastosowaniem jest Java .pliki właściwości, gdy "stałe" mogą być zdefiniowane w czasie wykonywania, ale nie można łatwo zmienić użytkownika. Możesz je spakować .słoiki i odwołaj je do klasy resourceLoader.

 13
Author: Yann Ramin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-15 20:26:15

That ' s the right way to go.

Zazwyczaj stałe są NIE przechowywane w oddzielnych klasach "stałych", ponieważ nie są wykrywalne. Jeśli stała jest istotna dla bieżącej klasy, utrzymanie jej tam pomaga następnemu programiście.

 6
Author: Jason Cohen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-15 19:44:16

A co z wyliczeniem?

 5
Author: Sébastien D.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-15 19:50:34

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

Jedną z zalet jest to, że jeśli twój program przerasta stałą-przekonasz się, że musi być konfigurowalna-możesz po prostu zmienić sposób, w jaki getter zwraca stałą.

Inną korzyścią jest to, że aby zmodyfikować stałą, nie musisz przekompilować wszystkiego, co jej używa. Gdy odwołujesz się do statycznego ostatnie pole, wartość tej stałej jest kompilowana do dowolnego bajtowego kodu, który się do niej odwołuje.

 5
Author: big_peanut_horse,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-16 01:30:29

Zgadzam się, że korzystanie z Interfejsu nie jest dobrym rozwiązaniem. Unikanie tego wzorca ma nawet swój własny element (#18) W efektywnej Javy Blocha.

Argument Bloch przeciw stałemu wzorcowi interfejsu jest taki, że użycie stałych jest szczegółem implementacji, ale implementacja interfejsu do ich użycia ujawnia te szczegóły implementacji w eksportowanym interfejsie API.

Wzór public|private static final TYPE NAME = VALUE; jest dobrym sposobem deklarowania stałej. Osobiście uważam, że lepiej unikać oddzielna Klasa, żeby pomieścić wszystkie Twoje stałe, ale nigdy nie widziałem powodu, żeby tego nie robić, poza osobistymi preferencjami i stylem.

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

Jeśli używasz wersji wcześniejszej niż 1.5, nadal możesz pobierać typy używając zwykłych klas Javy. (Zobacz ta strona aby uzyskać więcej na ten temat).

 5
Author: Rob Dickerson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-29 07:22:50

Bazując na powyższych komentarzach uważam, że jest to dobre podejście do zmiany staromodnej klasy stałej globalnej (posiadającej publiczne statyczne zmienne końcowe) na jej odpowiednik enum w sposób podobny do tego:

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ę je odnieść do takich jak:

Constants.StringConstant.DB_HOST
 4
Author: Lorand Bendig,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-27 09:39:36

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

 3
Author: Bradley Harris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-28 21:12:28

Istnieje pewna ilość opinii, aby odpowiedzieć na to pytanie. Na początek, stałe w Javie są zazwyczaj deklarowane jako publiczne, statyczne i końcowe. Poniżej znajdują się 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 stałego accesora / obiektu, ponieważ oczekuje się, że interfejsy zostaną zaimplementowane. Czy to nie wygląda śmiesznie:

String myConstant = IMyInterface.CONSTANTX;

Zamiast tego wybrałbym kilka różnych sposobów, w oparciu o kilka małych kompromisów, a więc to zależy od tego, co Ty need:

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
 2
Author: djangofan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-08 22:06:32

Jaki jest najlepszy sposób implementacji stałych w Javie?

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

Tworzenie interfejsu specjalnie do deklarowania stałych jest naprawdę najgorszą rzeczą : pokonuje powód, dla którego interfejsy zostały zaprojektowane : definiowanie metody(metod) umowy.

Nawet jeśli interfejs już istnieje, aby zaspokoić określoną potrzebę, deklarowanie stałych w nich sprawia, że naprawdę nie stałe sense as nie powinny być częścią API i umowy dostarczanej klasom klienta.


Aby uprościć, Mamy zasadniczo 4 ważne podejścia .

Z static final String/Integer pole:

  • 1) użycie klasy, która deklaruje stałe wewnątrz, ale nie tylko.
  • 1 variant) Tworzenie klasy dedykowanej tylko do deklarowania stałych.

Z Java 5 enum:

  • 2) deklarowanie enum w pokrewnej klasie celu (tak jak zagnieżdżone klasy).
  • 2 variant) tworzenie enum jako samodzielnej klasy (tak zdefiniowanej we własnym pliku klas).

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

W większości przypadków sposób enum jest prawdopodobnie lepszy niż static final String/Integer sposób i osobiście uważam, że sposób static final String/Integer powinien być używany tylko wtedy, gdy mamy dobre powody, aby nie używać enum.
I o tym, gdzie powinniśmy deklarować wartości stałe, chodzi o to, aby szukać czy istnieje jedna istniejąca klasa, która posiada określoną i silną spójność funkcjonalną o stałych wartościach. Jeśli znajdziemy taką klasę, powinniśmy użyć jej jako posiadacza stałych . W przeciwnym razie stała nie powinna być powiązana z żadną konkretną klasą.


static final String/ static final Integer versus enum

Użycie Enums jest naprawdę sposobem na silne rozważenie.
Enum ma dużą przewagę nad String lub Integer stałym polem.
Ustawili mocniejszy ograniczenie kompilacji. Jeśli zdefiniujesz metodę, która przyjmuje enum jako parametr, możesz przekazać tylko wartość enum zdefiniowaną w klasie enum (lub null).
Z String i Integer można zastąpić je dowolnymi wartościami zgodnego typu i Kompilacja będzie dobra nawet jeśli wartość nie jest zdefiniowaną stałą w static final String/ static final Integer pola.

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

public class MyClass{

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

Tutaj metoda, która oczekuje, że jeden z tych stałe jako parametr:

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

Możesz wywołać go 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 pojawi się tylko w czasie wykonywania i tylko wtedy, gdy wykonasz sprawdzenie przesyłanej wartości.

W przypadku enum sprawdzanie nie jest wymagane, ponieważ klient może przekazać tylko wartość enum w parametrze enum.

Na przykład tutaj dwie wartości zdefiniowane w enum Klasa (tak stała z pudełka):

public enum MyEnum {

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

    private String value;

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

Tutaj metoda, która spodziewa się mieć jedną z tych wartości enum jako parametr:

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

Możesz wywołać go 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 deklarować stałe ?

Jeśli aplikacja zawiera jedną istniejącą klasę, która posiada specyficzną i silną spójność funkcjonalną przy wartościach stałych 1) i 2) wydają się bardziej intuicyjne.
Ogólnie rzecz biorąc, ułatwia użycie stałych, jeśli są one zadeklarowane w głównej klasie, która nimi manipuluje lub która ma nazwę bardzo naturalną, aby zgadnąć, ż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 Klasa. Mogą więc łatwo znaleźć stałe i zapamiętać, gdzie E i PI są 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, sposoby 1) i 2) wydają się bardziej intuicyjne.
Ogólnie rzecz biorąc, nie ułatwia to 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, jak i żadna z tych klas nie wydaje się być bardziej naturalna od innych, aby hostować stałe wartości.
Tutaj zdefiniowanie niestandardowej klasy, która przechowuje tylko stałe wartości, ma sens.
Na przykład w bibliotece JDK, java.util.concurrent.TimeUnit enum nie jest zadeklarowane w określonej klasie, ponieważ nie istnieje tak naprawdę jedna i tylko jedna klasa specyficzna dla JDK, która wydaje się najbardziej intuicyjna do przechowywania:

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

Wiele klas zadeklarowanych w java.util.concurrent używa ich : BlockingQueue, ArrayBlockingQueue<E>, CompletableFuture, ExecutorService , ... i naprawdę nikt z nich nie wydaje się bardziej odpowiedni do trzymania enum.

 2
Author: davidxxx,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-29 12:41:07

Stała dowolnego typu może być zadeklarowana przez utworzenie niezmiennej właściwości wewnątrz klasy (która jest zmienną składową z modyfikatorem final). Zazwyczaj dostarczane są również modyfikatory static i public.

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

Istnieje wiele zastosowań, w których wartość stałej wskazuje wybór z N-krotki (np. wyliczenie) wyborów. W naszym przykładzie możemy zdefiniować typ wyliczeniowy, który ograniczy możliwe przypisane wartości (np. ulepszony Typ-bezpieczeństwo):

public class OfficePrinter {
    public enum PrinterState { Ready, PCLoadLetter, OutOfToner, Offline };
    public static final PrinterState STATE = PrinterState.Ready;
}
 1
Author: Ryan Delucchi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-15 21:17:31

Pojedyncza, OGÓLNA Klasa stałych to zły pomysł. Stałe powinny być pogrupowane razem z klasą, z którą są najbardziej logicznie związane.

Zamiast używać zmiennych wszelkiego rodzaju (zwłaszcza enum), sugerowałbym użycie metod. Utwórz metodę o tej samej nazwie co zmienna i zwróć jej wartość przypisaną do zmiennej. Teraz Usuń zmienną i Zastąp wszystkie odniesienia do niej wywołaniami do właśnie utworzonej metody. Jeśli czujesz, że stała jest na tyle ogólny, że nie trzeba tworzyć instancji klasy tylko po to, aby ją użyć, a następnie uczynić metodę stałą metodą klasy.

 1
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-15 22:17:12

FWIW, wartość timeout w sekundach powinna być prawdopodobnie ustawieniem konfiguracyjnym (wczytanym z pliku Właściwości lub poprzez wtrysk jak w Springu), a nie stałą.

 1
Author: Tim Howland,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-16 01:33:07

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 za pomocą MyGlobalConstants.TIMEOUT_IN_SECS gdziekolwiek potrzebujemy tej stałej. Myślę, że oba są takie same.

 1
Author: chandrayya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-05 06:15:45

Nie nazwałbym klasy tak samo (poza obudową) jak stałej ... Chciałbym mieć co najmniej jedną klasę "Settings", lub "Values", lub "Constants", gdzie wszystkie stałe będą żyć. Jeśli mam ich dużą liczbę, grupowałbym je w logiczne stałe klasy (UserSettings, AppSettings, itp.)

 0
Author: Joel Martinez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-15 19:41:23

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. Np.

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

Ale nie wdrażaj go. Wystarczy odnieść się do nich bezpośrednio w kodzie Poprzez w pełni kwalifikowaną nazwę klasy.

 0
Author: Andrew Harmel-Law,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-15 19:45:34

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

Public class 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 }


}
 0
Author: mmansoor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-15 20:45:52

Jednym ze sposobów, w jaki to robię, jest tworzenie 'globalnej' klasy ze stałymi wartościami i Dokonywanie importu statycznego w klasach, które potrzebują dostępu do stałej.

 0
Author: Javamann,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-15 21:44:56

static final to moje preferencje, użyłbym tylko enum, Jeśli element rzeczywiście można wyliczyć.

 0
Author: wulfgarpro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-31 01:49:03

Używam static final do deklarowania stałych i idę z notacją nazw ALL_CAPS. Widziałem kilka rzeczywistych przypadków, w których wszystkie stałe są połączone ze sobą w interfejs. Kilka postów słusznie nazwało to złą praktyką, przede wszystkim dlatego, że nie po to jest interfejs. Interfejs powinien egzekwować umowę i nie powinien być miejscem do umieszczania niepowiązanych stałych. Umieszczenie go razem w klasie, której nie można utworzyć instancji (przez prywatny konstruktor) jest dobre, jeśli stała semantyka nie należy do określonej klasy(klas). Zawsze umieszczam stałą w klasie, z którą jest najbardziej związana, ponieważ ma to sens i jest również łatwe do utrzymania.

Liczby są dobrym wyborem do reprezentowania zakresu wartości, ale jeśli przechowujesz stałe samodzielne z naciskiem na wartość bezwzględną (np. TIMEOUT = 100 ms) można po prostu przejść do podejścia static final.

 0
Author: bincob,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-15 12:45:24

Zgadzam się z tym, co większość mówi, najlepiej używać enums, gdy mamy do czynienia ze zbiorem stałych. Jeśli jednak programujesz w systemie Android, jest lepsze rozwiązanie: IntDef Annotation .

@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 jest lepsza od enum w jeden prosty sposób, zajmuje znacznie mniej miejsca, ponieważ jest po prostu znacznikiem czasu kompilacji. Nie jest klasą, ani nie posiada właściwości automatic string-conversion.

 0
Author: Quinn Turner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-20 19:37:31

To jest zły nawyk i strasznie Irytująca praktyka cytowania Joshuy Blocha bez zrozumienia podstawowego fundamentalizmu ground-zero.

Nic nie czytałem, więc albo

    Jest okropnym programistą.]} Albo ludzie, których do tej pory cytuję (Joshua to imię chłopca, jak przypuszczam) po prostu używają jego materiału jako religijnych skryptów, aby uzasadnić swoje oprogramowanie religijnych odpustów.
Jak w fundamentalizmie biblijnym Wszystkie prawa biblijne można podsumować
    Kochaj fundamentalną tożsamość całym swoim sercem i całym umysłem]} Kochaj bliźniego swego jak siebie samego]}

I tak podobnie fundamentalizm inżynierii oprogramowania można podsumować przez

  • poświęć się podstawom ground-zero z całą swoją programową mocą i umysłem
  • i poświęć się doskonałości swoich kolegów-programistów, tak jak ty sam.

Także, wśród biblijnych kręgów fundamentalistycznych ciągnie się silna i rozsądna następczyni

    Pierwsza miłość do siebie. Ponieważ jeśli nie kochasz siebie za bardzo, to pojęcie " Kochaj bliźniego jak siebie samego "nie ma większego znaczenia, ponieważ" jak bardzo kochasz siebie " jest linią odniesienia, powyżej której kochałbyś innych.

Podobnie, jeśli nie szanujesz siebie jako programisty i po prostu akceptujesz wypowiedzi i przepowiednie jakiegoś Guru programowania-nath bez kwestionowanie podstaw, Twoich cytatów i poleganie na Joshui Bloch (i tym podobnych) jest bez znaczenia. I dlatego tak naprawdę nie miałbyś szacunku dla swoich kolegów-programistów.

Podstawowe prawa programowania

  • lenistwo jest cnotą dobrego programisty
  • masz uczynić swoje życie programistyczne tak łatwym, leniwym, a tym samym tak skutecznym, jak to tylko możliwe
  • masz sprawić, że konsekwencje i wnętrzności twojego programowania będą tak łatwe, tak leniwy, a zatem tak skuteczny, jak to możliwe dla twoich sąsiadów-programistów, którzy pracują z Tobą i podnoszą twoje wnętrzności programistyczne.

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

Na jakich prawach fundamentalnie skutecznego i odpowiedzialnego programowania podlega ten religijny edykt ?

Po prostu przeczytaj artykuł na Wikipedii o stałych wzorców interfejsu ( https://en.wikipedia.org/wiki/Constant_interface ), i głupie wymówki, które stwierdza przeciwko stałe wzorca interfejsu.

  • Whatif-No IDE? Kto jako programista nie użyłby IDE? Większość z nas to programiści, którzy wolą nie musieć udowadniać, że mają macho aescetyczny survivalystyzm, unikając użycia IDE.

    • również-poczekaj chwilę na programowanie mikro-funkcjonalne jako sposób, aby nie potrzebować IDE. Poczekaj, aż przeczytasz moje wyjaśnienie dotyczące normalizacji modelu danych.
  • Zanieczyszcza przestrzeń nazw ze zmiennymi nie używanymi w bieżącym zakresie? To może być zwolennicy tej opinii

      Nie są świadomi i potrzeby normalizacji modelu danych.]}
  • Używanie interfejsów do wymuszania stałych jest nadużyciem interfejsów. Zwolennicy takich mają zły nawyk

    • nie widząc ,że "stałe" muszą być traktowane jako kontrakt. A Interfejsy służą do egzekwowania lub przewidywania zgodności z umową.
  • It konwersja interfejsów na zaimplementowane klasy w przyszłości jest trudna, jeśli nie niemożliwa. Hah .... hmmm ... ???

    • dlaczego chcesz angażować się w taki schemat programowania, jak twoje uporczywe źródło utrzymania? IOW, po co się poświęcać tak AMBIWALENTNEMU i złemu nawykowi programistycznemu ?

Niezależnie od wymówek, nie ma ważnej wymówki, jeśli chodzi o zasadniczo skuteczną inżynierię oprogramowania, aby delegitymizować lub ogólnie zniechęcić do korzystania z stałe interfejsu.

Nie ma znaczenia, jakie były pierwotne intencje i stany psychiczne ojców założycieli, którzy stworzyli Konstytucję Stanów Zjednoczonych. Moglibyśmy debatować nad pierwotnymi intencjami ojców założycieli, ale zależy mi tylko na pisemnych oświadczeniach Konstytucji USA. I obowiązkiem każdego obywatela USA jest wykorzystanie pisanego literacko-fundamentalizmu, a nie niepisanych założeń Konstytucji USA.

Podobnie, nie obchodzi mnie, co "oryginalne" zamiary twórców platformy Java i języka programowania miały dla interfejsu. Zależy mi na efektywnych funkcjach, jakie dostarcza Specyfikacja Java i zamierzam w pełni wykorzystać te funkcje, aby pomóc mi spełnić podstawowe prawa odpowiedzialnego programowania. Nie obchodzi mnie, czy jestem postrzegany jako "naruszający intencje 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 / align = "left" /

Podstawą jest normalizacja modelu danych

Nie ma znaczenia, w jaki sposób model danych jest hostowany lub przesyłany. Niezależnie od tego, czy używasz interfejsów, enum, czy czegokolwiek innego, relacyjnego, czy nie-SQL, jeśli nie rozumiesz potrzeby i procesu normalizacji modelu danych.

Musimy najpierw zdefiniować i znormalizować model danych zbioru procesów. A gdy mamy spójny model danych, tylko wtedy możemy wykorzystać przepływ procesu jego komponenty do definiowania zachowania Funkcjonalnego i procesu blokuje pole lub sferę aplikacji. I dopiero wtedy możemy zdefiniować API każdego procesu funkcjonalnego.

Nawet aspekty normalizacji danych zaproponowane przez EF Codd są teraz poważnie kwestionowane i poważnie kwestionowane. np. jego wypowiedź na temat 1NF została skrytykowana jako niejednoznaczna, niewłaściwa i nadmiernie uproszczona, podobnie jak reszta jego wypowiedzi, zwłaszcza w nadejściu nowoczesnych usług danych, technologii repo i transmisja. IMO, deklaracje EF Codd powinny zostać całkowicie porzucone i zaprojektować nowy zestaw bardziej matematycznie wiarygodnych twierdzeń.

[4]}rażącą wadą EF Codda i przyczyną jego niewspółosiowości do efektywnego ludzkiego zrozumienia jest jego przekonanie, że postrzegalne po ludzku wielowymiarowe, zmienny wymiar dane mogą być skutecznie postrzegane za pomocą zestawu fragmentarycznych mapowań 2-wymiarowych.

Podstawy normalizacji danych

Co nie udało się EF Codd express.

W ramach każdego spójnego modelu danych, są to sekwencyjny stopniowany porządek spójności modelu danych do osiągnięcia.

  1. jedność i tożsamość instancji danych.
    • Zaprojektuj ziarnistość każdego komponentu danych, przy czym ich ziarnistość jest na poziomie, na którym każda instancja komponentu może być jednoznacznie zidentyfikowana i pobrana.
    • brak aliasingu instancji. tj. nie istnieją żadne środki, dzięki którym identyfikacja wytwarza więcej niż jedną instancję komponent.
  2. brak przesłuchu instancji. Nie istnieje konieczność użycia jednej lub więcej innych instancji komponentu, aby przyczynić się do identyfikacji instancji komponentu.
  3. jedność i tożsamość składników/wymiarów danych.
    • obecność de-aliasingu komponentów. Musi istnieć jedna definicja, w której element / wymiar może być jednoznacznie zidentyfikowany. Która jest podstawową definicją składnika;
    • gdzie podstawowy definicja nie spowoduje ujawnienia pod-wymiarów lub elementów składowych, które nie są częścią zamierzonego komponentu;
  4. unikalny sposób obsługi komponentów. Musi istnieć jedna, i tylko jedna, taka definicja de-aliasingu komponentu.
  5. istnieje jeden i tylko jeden interfejs definicji lub kontrakt służący do identyfikacji komponentu nadrzędnego w hierarchicznej relacji komponentów.
  6. brak przesłuchu komponentu. Nie istnieje konieczność użycia członu innego komponentu w celu przyczynienia się do ostatecznej identyfikacji komponentu.
    • w takiej relacji rodzic-dziecko definicja identyfikująca rodzica nie może zależeć od części zbioru składników członkowskich dziecka. Elementem składowym tożsamości rodzica musi być pełna tożsamość dziecka bez odwoływania się do któregokolwiek lub wszystkich dzieci dziecka.
  7. Preempt BI-modal lub multi-modal wygląd model danych.
    • gdy istnieją dwie definicje kandydata komponentu, jest to oczywisty znak, że istnieją dwa różne modele danych mieszane jako jeden. Oznacza to, że na poziomie modelu danych lub na poziomie pola występuje niespójność.
    • Pole aplikacji musi wykorzystywać jeden i tylko jeden model danych, spójnie.
  8. wykryć i zidentyfikować mutację składników. Jeśli nie wykonałeś statystycznej analizy składowej ogromnych danych, prawdopodobnie nie zobacz, lub zobacz potrzebę leczenia, mutacji składników.
    • model danych może powodować, że niektóre jego składniki mutują cyklicznie lub stopniowo.
    • tryb może być member-rotation lub transposition-rotation.
    • mutacja Member-rotation może być odrębną zamianą komponentów potomnych między komponentami. Lub gdzie trzeba by zdefiniować zupełnie nowe komponenty.
    • mutacja Transpozycyjna przejawiałaby się jako członek wymiarowy mutujący w atrybut, vice versa.
    • każdy cykl mutacji musi być zidentyfikowany jako odrębny modal danych.
  9. wersjonowanie każdej mutacji. Takie, że można wyciągnąć poprzednią wersję modelu danych, Gdy być może pojawi się potrzeba leczenia 8-letniej mutacji modelu danych.

W polu lub siatce międzyobsługowych aplikacji komponentowych, musi istnieć jeden i tylko jeden spójny model danych lub istnieje środek do identyfikacji modelu/wersji danych.

Czy jesteśmy wciąż pytasz, czy możemy użyć stałych interfejsu? Naprawdę ?

W grę wchodzą kwestie normalizacji danych bardziej wynikowe niż to przyziemne pytanie. Jeśli nie rozwiążesz tych problemów, zamieszanie, które Twoim zdaniem powodują stałe interfejsu, jest stosunkowo niczym. Nic.

Z normalizacji modelu danych można określić składniki jako zmienne, jako właściwości, jako stałe interfejsu umowy.

Następnie określasz, które przechodzi do iniekcji wartości, własności konfiguracja zastępcza, interfejsy, końcowe ciągi znaków itp.

Jeśli musisz użyć wymówki konieczności zlokalizowania komponentu łatwiejszego do dyktowania względem stałych interfejsu, oznacza to, że masz zły nawyk nie praktykowania normalizacji modelu danych.

Być może chcesz skompilować model danych do wydania vcs. Że można wyciągnąć wyraźnie identyfikowalną wersję modelu danych.

Wartości zdefiniowane w interfejsach są całkowicie pewne, że nie podlegają zmianom. Oraz możliwość udostępniania. Po co ładować zestaw końcowych ciągów do swojej klasy z innej klasy, skoro wszystko czego potrzebujesz to ten zestaw stałych ??

Dlaczego więc nie opublikować umowy na wzór danych? To znaczy, jeśli można zarządzać i normalizować go spójnie, 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 taki sposób, jak

CustomerService.Label.Address.Street
CustomerService.Label.Person.NameParts.Family
To myli zawartość pliku jar? Jako programista Java nie obchodzi mnie struktura jar.

To przedstawia złożoność do zamiany środowiska uruchomieniowego motywowanego przez osgi ? Osgi jest niezwykle skutecznym środkiem pozwalającym programistom na kontynuowanie złych nawyków. Istnieją lepsze alternatywy niż osgi.

Albo dlaczego nie to? Nie ma wycieku stałych prywatnych do opublikowanej umowy. Wszystkie stałe prywatne powinny być pogrupowane w prywatny interfejs o nazwie "stałe", ponieważ nie chcę szukać stałych i jestem zbyt leniwy, aby wielokrotnie wpisywać "private final String".
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 implementacja interfejsu.

To nie jest "pierwotna intencja" interfejsów? Jakby mnie interesowała "pierwotna intencja" ojców założycieli w tworzeniu Konstytucji USA, a nie jak Sąd Najwyższy zinterpretuje pisane listy Konstytucji USA ???

W końcu żyję w Krainie wolnych, dzikich i domu odważnych. Bądź odważny, bądź wolny, bądź dziki - Użyj interfejsu. Jeśli moi koledzy-Programiści odmawiają używania wydajnych i leniwych środków programowania, czy jestem zobowiązany przez złotą zasadę do zmniejszenia mojej wydajności programowania, aby dostosować się do ich? Być może powinienem, ale to nie jest idealna sytuacja.
 0
Author: Blessed Geek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-10 12:18:44