Каков наилучший способ реализации констант в Java?

Я видел такие примеры:

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

и предположил, что у меня может быть класс Constants для обертывания констант, объявляя их статическим окончательным. Я практически не знаю Java, и мне интересно, является ли это лучшим способом создания констант.

Ответ 1

Это вполне приемлемо, возможно, даже стандарт.

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

где TYPE - тип, NAME - это имя во всех шапках с символами подчеркивания для пробелов, а VALUE - постоянное значение;

Я настоятельно рекомендую НЕ помещать ваши константы в свои собственные классы или интерфейсы.

В качестве примечания: переменные, объявленные окончательными и изменяемые, могут быть изменены; однако переменная никогда не может указывать на другой объект.

Например:

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

public static void main(String[] args){

    ORIGIN.x = 3;

}

Это законно и ORIGIN тогда будет точкой в ​​(3, 0).

Ответ 2

Я бы очень советовал не иметь один класс констант. В то время это может показаться хорошей идеей, но когда разработчики отказываются документировать константы, и класс растет, чтобы охватить свыше 500 констант, которые все не связаны друг с другом вообще (связанные с совершенно разными аспектами приложения), это обычно превращается в файл констант, который полностью нечитаем. Вместо этого:

  • Если у вас есть доступ к Java 5+, используйте перечисления для определения ваших конкретных констант для области приложения. Для этих констант все части области приложения должны ссылаться на перечисления, а не на постоянные значения. Вы можете объявить перечисление, подобное тому, как вы объявляете класс. Перечисления - это, пожалуй, самая (и, возможно, только) полезная функция Java 5 +.
  • Если у вас есть константы, которые действительны только для определенного класса или одного из его подклассов, объявите их защищенными или общедоступными и поместите их в верхний класс в иерархии. Таким образом, подклассы могут получить доступ к этим постоянным значениям (и если другие классы обращаются к ним через public, константы не только действительны для определенного класса... что означает, что внешние классы, использующие эту константу, могут быть слишком тесно связаны с класс, содержащий константу)
  • Если у вас есть интерфейс с определенным поведением, но возвращаемые значения или значения аргументов должны быть конкретными, вполне допустимо определить константы на этом интерфейсе, чтобы другие разработчики имели доступ к ним. Однако, избегайте создания интерфейса, чтобы просто удерживать константы: он может стать столь же плохим, как класс, созданный только для того, чтобы удерживать константы.

Ответ 3

Это БЕСПЛАТНАЯ ПРАКТИКА, чтобы использовать интерфейсы только для того, чтобы удерживать константы (так называемый шаблон с постоянным интерфейсом Джоша Блоха). Вот что Джош советует:

Если константы сильно привязаны к существующий класс или интерфейс, вы следует добавить их в класс или интерфейс. Например, все числовые примитивные классы в штучной упаковке, такие как Integer и Double, экспорт MIN_VALUE и MAX_VALUE. Если константы лучше всего рассматривать как членов перечисленного типа, вы должен экспортировать их с перечислениемтип. В противном случае вы должны экспортировать константы с нерушимым полезный класс.

Пример:

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

Об именовании:

По соглашению, такие поля имеют имена состоящий из заглавных букв, с слова, разделенные символами подчеркивания. это что эти поля содержат либо примитивные значения, либо ссылки к неизменяемым объектам.

Ответ 4

В Effective Java (2-е издание) рекомендуется использовать переменные вместо статических ints для констант.

Там есть хорошая запись в enums в Java: http://java.sun.com/j2se/1.5.0/docs/guide/language/enums.html

Обратите внимание, что в конце этой статьи возникает вопрос:

Итак, когда вы должны использовать перечисления?

С ответом:

Каждый раз, когда вам нужен фиксированный набор констант

Ответ 5

Просто избегайте использования интерфейса:

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

public class NeddsConstant implements MyConstants {

}

Это заманчиво, но нарушает инкапсуляцию и стирает различие определений классов.

Ответ 6

Я использую следующий подход:

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() {}
}

Чем, например, я использую Constants.DB.Connection.URL для получения константы. Он выглядит более "объектно ориентированным", как для меня.

Ответ 7

Создание статических конечных констант в отдельном классе может вызвать у вас проблемы. Компилятор Java фактически оптимизирует это и поместит фактическое значение константы в любой класс, который ссылается на него.

Если вы позже измените класс "Константы", и вы не выполните сложную перекомпилировать другие классы, которые ссылаются на этот класс, вы соберете комбинацию старых и новых значений.

Вместо того, чтобы думать об этом как о константах, подумайте о них как параметрах конфигурации и создайте класс для управления ими. Измените значения, которые не являются окончательными, и даже подумайте об использовании геттеров. В будущем, когда вы определите, что некоторые из этих параметров на самом деле должны быть настроены пользователем или администратором, это будет намного проще сделать.

Ответ 8

Ошибка номер один, которую вы можете создать, - это создать глобально доступный класс с общим именем, например Constants. Это просто завалено мусором, и вы теряете все возможности выяснить, какая часть вашей системы использует эти константы.

Вместо этого константы должны войти в класс, который "владеет" им. У вас есть константа, называемая TIMEOUT? Вероятно, это должно перейти в ваш класс Communications() или Connection(). MAX_BAD_LOGINS_PER_HOUR? Входит в User(). И так далее.

Другое возможное использование - файлы Java.properties, когда "константы" могут быть определены во время выполнения, но не легко меняются пользователем. Вы можете упаковать их в свои .jars и ссылаться на них с помощью класса resourceLoader.

Ответ 9

Это правильный путь.

Обычно константы не хранятся в отдельных классах "Константы", потому что они не доступны для обнаружения. Если константа относится к текущему классу, сохранение их там помогает следующему разработчику.

Ответ 10

Как насчет перечисления?

Ответ 11

Я согласен, что использование интерфейса - это не путь. Избегание этого шаблона даже имеет свой собственный элемент (# 18) в блохе Эффективная Java.

Аргумент Блоха в отношении шаблона постоянного интерфейса заключается в том, что использование констант является детальностью реализации, но реализация интерфейса для их использования предоставляет эту деталь реализации в экспортированном API.

Шаблон public|private static final TYPE NAME = VALUE; - хороший способ объявления константы. Лично я считаю, что лучше не создавать отдельный класс для размещения всех ваших констант, но я никогда не видел причин не делать этого, кроме личных предпочтений и стиля.

Если ваши константы могут быть хорошо смоделированы как перечисление, рассмотрите структуру enum, доступную в 1.5 или более поздней версии.

Если вы используете версию более ранней версии 1.5, вы все равно можете отменить перечисления типов, используя обычные классы Java. (Подробнее об этом см. этот сайт).

Ответ 12

Я предпочитаю использовать геттеры, а не константы. Эти геттеры могут возвращать постоянные значения, например. public int getMaxConnections() {return 10;}, но все, что нуждается в константе, будет проходить через getter.

Одно из преимуществ заключается в том, что если ваша программа перерастает константу - вы обнаружите, что ее нужно настраивать - вы можете просто изменить способ получения константы константой.

Другое преимущество заключается в том, что для изменения константы вам не нужно перекомпилировать все, что ее использует. Когда вы ссылаетесь на статическое конечное поле, значение этой константы компилируется в любой байт-код, который ссылается на него.

Ответ 13

Основываясь на вышеприведенных комментариях, я думаю, что это хороший подход, чтобы изменить старомодный глобальный постоянный класс (имеющий общедоступные статические конечные переменные) на его эквивалент-эквивалент таким образом:

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

}

Итак, я могу ссылаться на них следующим образом:

Constants.StringConstant.DB_HOST

Ответ 14

Хороший объектно-ориентированный дизайн не должен нуждаться во многих общедоступных константах. Большинство констант должны быть инкапсулированы в класс, который требует от них выполнения своей работы.

Ответ 15

На это есть определенное мнение. Для начала константы в java обычно объявляются публичными, статическими и конечными. Ниже приведены причины:

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

Я бы никогда не использовал интерфейс для объекта/объекта CONSTANTS просто потому, что обычно предполагается, что интерфейсы будут реализованы. Разве это не выглядит смешно:

String myConstant = IMyInterface.CONSTANTX;

Вместо этого я бы выбрал несколько разных способов, основанных на некоторых небольших компромиссах, и поэтому это зависит от того, что вам нужно:

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

Ответ 16

Каков наилучший способ реализации констант в Java?

Один подход, которого мы должны избегать: использование интерфейсов для определения констант.

Создание интерфейса, специально предназначенного для объявления констант, на самом деле является наихудшей вещью: оно побеждает причину, по которой были разработаны интерфейсы: определение метода (ов) контракта.

Даже если интерфейс уже существует для удовлетворения конкретной потребности, объявление констант в них не имеет смысла, так как константы не должны составлять часть API и контракта, предоставляемого клиентским классам.


Чтобы упростить, у нас есть в целом 4 действительных подхода.

Со static final String/Integer полем static final String/Integer:

  • 1) использование класса, который объявляет константы внутри, но не только.
  • 1 вариант) создание класса, предназначенного только для объявления констант.

С Java 5 enum:

  • 2) объявление перечисления в связанном целевом классе (например, во вложенном классе).
  • 2 вариант) создание перечисления в виде отдельного класса (определенного в его собственном файле классов).

TL;DR: Какой путь лучше и где найти константы?

В большинстве случаев путь enum, вероятно, более тонкий, чем static final String/Integer путь static final String/Integer , и лично я считаю, что static final String/Integer путь static final String/Integer следует использовать, только если у нас есть веские причины не использовать перечисления.
Что касается того, где мы должны объявлять постоянные значения, идея состоит в том, чтобы искать, существует ли единственный существующий класс, который обладает определенной и сильной функциональной связностью с постоянными значениями. Если мы найдем такой класс, мы должны использовать его в качестве держателя констант. В противном случае константа не должна быть связана ни с одним конкретным классом.


static final String/static final Integer против enum

Использование Enums действительно способ, который настоятельно рекомендуется.
Перечисления имеют большое преимущество перед полем констант String или Integer.
Они устанавливают более жесткие ограничения компиляции. Если вы определяете метод, который принимает перечисление в качестве параметра, вы можете передать только значение перечисления, определенное в классе перечисления (или ноль).
С помощью String и Integer вы можете заменить их любыми значениями совместимого типа, и компиляция будет в порядке, даже если это значение не является определенной константой в полях static final String/static final Integer static final String.

Например, ниже двух констант, определенных в классе как static final String поля static final String:

public class MyClass{

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

Вот метод, который ожидает иметь одну из этих констант в качестве параметра:

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

Вы можете вызвать это следующим образом:

process(MyClass.ONE_CONSTANT);

или же

process(MyClass.ANOTHER_CONSTANT);

Но никакое ограничение компиляции не мешает вам вызывать его следующим образом:

process("a not defined constant value");

Вы будете иметь ошибку только во время выполнения и только если вы делаете за раз проверку переданного значения.

При использовании enum проверки не требуются, поскольку клиент может передать только значение enum в параметре enum.

Например, здесь два значения, определенные в классе enum (постоянные из коробки):

public enum MyEnum {

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

    private String value;

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

Вот метод, который ожидает иметь одно из этих значений перечисления в качестве параметра:

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

Вы можете вызвать это следующим образом:

process(MyEnum.ONE_CONSTANT);

или же

process(MyEnum.ANOTHER_CONSTANT);

Но компиляция никогда не позволит вам вызвать его таким образом:

process("a not defined constant value");

Где мы должны объявить константы?

Если ваше приложение содержит один существующий класс, который обладает определенной и сильной функциональной связью с постоянными значениями, то 1) и 2) кажутся более интуитивными.
Как правило, это облегчает использование констант, если они объявлены в главном классе, который ими манипулирует, или у которого есть имя, и очень естественно догадываться, что мы найдем его внутри.

Например, в библиотеке JDK экспоненциальные значения и значения констант pi объявляются в классе, который объявляет не только объявления констант (java.lang.Math).

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

Клиенты, использующие математические функции, часто полагаются на Math. Таким образом, они могут достаточно легко найти константы, а также могут запомнить, где E и PI определены очень естественным образом.

Если ваше приложение не содержит существующего класса, который имеет очень специфическую и сильную функциональную сплоченность с постоянными значениями, то варианты 1 и 2 будут казаться более интуитивными.
Как правило, это не облегчает использование констант, если они объявлены в одном классе, который ими манипулирует, в то время как у нас есть также 3 или 4 других класса, которые манипулируют ими так же, как и ни один из этих классов не кажется более естественным, чем другие. постоянные значения хоста.
Здесь определение пользовательского класса для хранения только постоянных значений имеет смысл.
Например, в библиотеке JDK перечисление java.util.concurrent.TimeUnit не объявлено в определенном классе, поскольку в действительности не существует одного и только одного конкретного класса JDK, который представляется наиболее интуитивным для его хранения:

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

Многие классы, объявленные в java.util.concurrent используют их: BlockingQueue, ArrayBlockingQueue<E>, CompletableFuture, ExecutorService ,... и на самом деле ни один из них не кажется более подходящим для хранения перечисления.

Ответ 17

Константа любого типа может быть объявлена ​​путем создания неизменяемого свойства, которое внутри класса (это переменная-член с модификатором final). Как правило, также предусмотрены модификаторы static и public.

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

Существует множество приложений, где постоянное значение указывает выбор из n-кортежа (например, перечисление) вариантов. В нашем примере мы можем выбрать опцию Enumerated Type, которая ограничит возможные присвоенные значения (то есть улучшенную безопасность типов):

public class OfficePrinter {
    public enum PrinterState { Ready, PCLoadLetter, OutOfToner, Offline };
    public static final PrinterState STATE = PrinterState.Ready;
}

Ответ 18

Один, общий класс констант - плохая идея. Константы должны быть сгруппированы вместе с классом, с которым они наиболее логически связаны.

Вместо использования переменных любого типа (особенно перечисления), я бы предложил использовать методы. Создайте метод с тем же именем, что и переменная, и верните значение, присвоенное переменной. Теперь удалите переменную и замените все ссылки на нее вызовами метода, который вы только что создали. Если вы считаете, что константа достаточно обобщена, вам не нужно создавать экземпляр класса, чтобы использовать его, а затем сделать метод константы методом класса.

Ответ 19

FWIW, значение тайм-аута в секундах, вероятно, должно быть настройкой конфигурации (считано из файла свойств или через инъекцию, как в Spring), а не константой.

Ответ 20

В чем разница

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

и используя MyGlobalConstants.TIMEOUT_IN_SECS, где нам нужна эта константа. Я думаю, что оба они одинаковы.

Ответ 21

Я бы не назвал класс тем же (кроме обложки) как константу... Я бы использовал как минимум один класс "Настройки", или "Значения", или "Константы", где все константы будет жить. Если у меня их много, я бы группировал их в логические постоянные классы (UserSettings, AppSettings и т.д.).

Ответ 22

Чтобы сделать это еще дальше, вы можете разместить глобально используемые константы в интерфейсе, чтобы их можно было использовать в системном масштабе. Например.

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

Но не выполняйте его. Просто обратитесь к ним непосредственно в код через полное имя класса.

Ответ 23

Для констант, Enum - лучший выбор ИМХО. Вот пример

открытый класс 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 }


}

Ответ 24

Один из способов сделать это - создать класс "Global" с постоянными значениями и сделать статический импорт в классах, которым нужен доступ к константе.

Ответ 25

static final - это мое предпочтение, я бы использовал только enum, если элемент действительно перечислил.

Ответ 26

Я использую static final для объявления констант и перехода с обозначением имен ALL_CAPS. Я видел довольно много реальных случаев жизни, когда все константы сгруппированы вместе в интерфейс. Несколько должностей по праву назвали эту плохую практику, прежде всего потому, что для этого не нужен интерфейс. Интерфейс должен обеспечивать выполнение контракта и не должен быть местом для размещения несвязанных констант. Объединение его в класс, который не может быть создан (через частный конструктор), тоже прекрасен, если константная семантика не относится к определенному классу ( эс). Я всегда ставил константу в классе, с которой она больше всего связана, потому что это имеет смысл, а также легко поддерживается.

Перечисления - хороший выбор для представления диапазона значений, но если вы сохраняете автономные константы с акцентом на абсолютное значение (например, TIMEOUT = 100 мс), вы можете просто пойти на подход static final.

Ответ 27

Я согласен с тем, что говорят большинство, лучше использовать перечисления при работе с набором констант. Однако, если вы программируете на Android, есть лучшее решение: Аннотации 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();

Аннотация IntDef превосходит перечисления одним простым способом, она занимает значительно меньше места, поскольку это просто маркер времени компиляции. Он не является классом и не имеет автоматического свойства преобразования строк.

Ответ 28

Плохая привычка и ужасно раздражающая практика - цитировать Джошуа Блоха без понимания основополагающего фундаментализма.

Я ничего не читал Джошуа Блох, так что либо

  • он ужасный программист
  • или люди, которых я нахожу, цитируя его (Джошуа - это имя мальчика, которого я предполагаю), просто используют его материалы в качестве религиозных сценариев для оправдания своей программной религиозной снисходительности.

Как и в библейском фундаментализме, все библейские законы могут быть обобщены

  • Любите фундаментальную идентичность всем своим сердцем и всем своим разумом
  • Люби ближнего как самого себя

и так же фундаментализм разработки программного обеспечения может быть суммирован

  • посвятите себя основополагающим основам со всей своей мощью программирования и умом
  • и посвятить себя совершенству ваших коллег-программистов, как вы бы для себя.

Кроме того, среди библейских фундаменталистских кругов обращается сильное и разумное следствие.

  • Сначала люби себя. Потому что, если вы не любите себя сильно, то концепция "любите своего ближнего как самого себя" не имеет большого значения, поскольку "как сильно вы любите себя" - это базовая линия, над которой вы любите других.

Точно так же, если вы не уважаете себя как программиста и просто принимаете высказывания и пророчества некоторых программистов-гуру, не ставя под сомнение основы, ваши цитаты и опора на Джошуа Блоха (и тому подобное) не имеют смысла. И поэтому вы на самом деле не будете уважать своих коллег-программистов.

Основные законы программирования

  • лень добродетель хорошего программиста
  • Вы должны сделать свою жизнь программирования настолько простой, ленивой и, следовательно, максимально эффективной
  • Вы должны сделать последствия и внутренности вашего программирования как можно более легкими, ленивыми и, следовательно, максимально эффективными для ваших соседей-программистов, которые работают с вами и подбирают ваши программистские ресурсы.

Константы шаблона интерфейса - плохая привычка???

В какие законы фундаментально эффективного и ответственного программирования входит этот религиозный указ?

Просто прочитайте статью в Википедии о константах шаблона интерфейса (https://en.wikipedia.org/wiki/Constant_interface), и глупо оправдывать ее константы шаблона интерфейса.

  • Whatif-нет IDE? Кто на земле как программист не будет использовать IDE? Большинство из нас - программисты, которые предпочитают не доказывать наличие мачо-аскетического выживания, избегая использования IDE.

    • Кроме того - подождите секунду сторонники микро-функционального программирования как средство не нуждающихся в IDE. Подождите, пока вы не прочитаете мое объяснение о нормализации модели данных.
  • Загрязняет пространство имен переменными, не используемыми в текущей области? Это могут быть сторонники этого мнения

    • не осведомлены и не нуждаются в нормализации модели данных
  • Использование интерфейсов для принудительного применения констант является злоупотреблением интерфейсами. Сторонники таких имеют плохую привычку

    • не видя, что "константы" должны рассматриваться как контракт. И интерфейсы используются для обеспечения или проецирования соответствия контракту.
  • В будущем трудно, если не невозможно, преобразовать интерфейсы в реализованные классы. Ха.... хммм...???

    • Почему вы хотите заниматься такой моделью программирования, как постоянные средства к существованию? Итак, зачем посвящать себя такой АМБИВАЛЕНТНОЙ и вредной привычке программирования?

Какими бы ни были оправдания, НЕТ ДЕЙСТВИТЕЛЬНОГО ПРИЧИНА, когда дело доходит до ФУНДАМЕНТАЛЬНО ЭФФЕКТИВНОЙ разработки программного обеспечения, чтобы делегитимизировать или вообще препятствовать использованию констант интерфейса.

Неважно, каковы были первоначальные намерения и психические состояния отцов-основателей, которые разработали Конституцию Соединенных Штатов. Мы могли бы обсудить первоначальные намерения отцов-основателей, но все, что меня волнует, - это письменные заявления Конституции США. И каждый гражданин США несет ответственность за использование письменного литературного фундаментализма, а не неписаных основополагающих принципов Конституции США.

Точно так же меня не волнует, какие "оригинальные" намерения основатели платформы Java и языка программирования имели для интерфейса. Меня волнуют эффективные функции, предоставляемые спецификацией Java, и я намерен использовать эти функции в полной мере, чтобы помочь мне выполнить основные законы ответственного программирования. Мне все равно, если меня воспринимают как "нарушающее намерение для интерфейсов". Мне все равно, что Гослинг или кто-то другой Блох говорит о "правильном способе использования Java", если только то, что они говорят, не нарушает мою потребность в ЭФФЕКТИВНОМ выполнении основ.

Основой является нормализация модели данных

Неважно, как ваша модель данных размещается или передается. Используете ли вы интерфейсы или перечисления или другие, реляционные или не-SQL, если вы не понимаете необходимости и процесса нормализации модели данных.

Сначала мы должны определить и нормализовать модель данных набора процессов. И когда у нас есть связная модель данных, ТОЛЬКО тогда мы можем использовать поток процессов его компонентов, чтобы определить функциональное поведение и блоки процессов в области или области приложений. И только тогда мы можем определить API каждого функционального процесса.

Даже аспекты нормализации данных, предложенные EF Codd, в настоящее время подвергаются серьезным и серьезным испытаниям. Например, его выражение о 1NF было подвергнуто критике как неоднозначное, смещенное и чрезмерно упрощенное, как и остальные его заявления, особенно в связи с появлением современных услуг передачи данных, технологий репо и передачи. IMO, заявления EF Codd должны быть полностью исключены, и должен быть разработан новый набор более математически правдоподобных утверждений.

Ярким недостатком Э. Ф. Кодда и причиной его несоответствия эффективному человеческому пониманию является его вера в то, что воспринимаемые человеком многомерные данные с изменчивыми измерениями могут быть эффективно восприняты посредством набора кусочных 2-мерных отображений.

Основы нормализации данных

Что Э. Ф. Кодд не смог выразить.

В рамках каждой последовательной модели данных это последовательный градуированный порядок достижения согласованности модели данных.

  1. Единство и идентичность экземпляров данных.
    • спроектировать детализацию каждого компонента данных, при этом их гранулярность находится на уровне, на котором каждый экземпляр компонента может быть уникально идентифицирован и получен.
    • отсутствие псевдонимов экземпляров. т.е. не существует средств, посредством которых идентификация производит более одного экземпляра компонента.
  2. Отсутствие примера перекрестных помех. Не существует необходимости использовать один или несколько других экземпляров компонента, чтобы способствовать идентификации экземпляра компонента.
  3. Единство и идентичность компонентов данных/измерений.
    • Наличие сглаживания компонентов. Должно существовать одно определение, посредством которого компонент/измерение может быть однозначно идентифицирован. Который является основным определением компонента;
    • где основное определение не приведет к раскрытию субразмерений или компонентов-элементов, которые не являются частью предполагаемого компонента;
  4. Уникальные средства компонентной разборки. Должно существовать одно и только одно такое определение сглаживания компонента для компонента.
  5. Существует один и только один интерфейс или контракт определения для идентификации родительского компонента в иерархической взаимосвязи компонентов.
  6. Отсутствие компонентных перекрестных помех. Не существует необходимости использовать элемент другого компонента, чтобы внести вклад в окончательную идентификацию компонента.
    • В таких отношениях родитель-потомок определение идентификатора родителя не должно зависеть от части набора компонентов-членов дочернего элемента. Компонент-член родительской идентичности должен быть полной дочерней личностью, не прибегая к ссылкам на всех или на всех детей ребенка.
  7. Превосходное бимодальное или мультимодальное появление модели данных.
    • Когда существует два определения кандидата для компонента, это является очевидным признаком того, что существуют две разные модели данных, смешанные в одну. Это означает, что существует несогласованность на уровне модели данных или на уровне поля.
    • Область приложений должна использовать одну и только одну модель данных, согласованно.
  8. Обнаружить и идентифицировать компонентную мутацию. Если вы не выполнили статистический компонентный анализ огромных данных, вы, вероятно, не увидите или не увидите необходимости лечения мутации компонентов.
    • Модель данных может иметь некоторые из своих компонентов мутировать циклически или постепенно.
    • Режим может быть вращением элемента или вращением перемещения.
    • Мутация ротации членов может быть явным обменом дочерних компонентов между компонентами. Или где совершенно новые компоненты должны быть определены.
    • Транспозиционная мутация проявляется в виде размерного члена, мутирующего в атрибут, и наоборот.
    • Каждый цикл мутации должен быть идентифицирован как отдельный мод данных.
  9. Версия каждой мутации. Таким образом, вы можете извлечь предыдущую версию модели данных, когда, возможно, возникнет необходимость в лечении 8-летней мутации модели данных.

В области или сетке взаимообслуживающих компонентных приложений должна существовать одна и только одна согласованная модель данных, или существует средство, позволяющее модели/версии данных идентифицировать себя.

Мы все еще спрашиваем, можем ли мы использовать интерфейсные константы? В самом деле?

На карту поставлены более важные вопросы нормализации данных, чем этот приземленный вопрос. Если вы не решите эти проблемы, путаница, которую, по вашему мнению, вызывают константы интерфейса, сравнительно ничто. Шиш.

Из нормализации модели данных вы определяете компоненты как переменные, как свойства, как константы интерфейса контракта.

Затем вы определяете, что входит в введение значения, заполнение конфигурации свойств, интерфейсы, финальные строки и т.д.

Если вы вынуждены использовать предлог для того, чтобы легче находить компонент для определения констант интерфейса, это означает, что у вас плохая привычка не практиковать нормализацию модели данных.

Возможно, вы хотите скомпилировать модель данных в выпуск vcs. Что вы можете вытащить четко идентифицируемую версию модели данных.

Значения, определенные в интерфейсах, гарантированно не изменяются. И поделился. Зачем загружать набор заключительных строк в ваш класс из другого класса, когда вам нужен только этот набор констант?

Так почему бы не опубликовать контракт модели данных? Я имею в виду, если вы можете согласованно и нормализовать это, то почему бы и нет?...

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

Теперь я могу ссылаться на контрактные ярлыки моих приложений таким образом, как

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

Это смущает содержимое файла JAR? Как программист на Java, я не забочусь о структуре фляги.

Это представляет сложность для OSGI-мотивированного обмена времени выполнения? Osgi - чрезвычайно эффективное средство, позволяющее программистам продолжать вредные привычки. Есть лучшие альтернативы, чем osgi.

Или почему не это? Нет утечки частных констант в опубликованный контракт. Все частные константы должны быть сгруппированы в частный интерфейс с именем "Константы", потому что я не хочу искать константы, и мне лень многократно набирать "private final String".

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

Возможно даже это:

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

Единственная проблема с интерфейсными константами, которую стоит рассмотреть, это когда интерфейс реализован.

Это не "оригинальное намерение" интерфейсов? Как будто меня заботит "первоначальное намерение" отцов-основателей при разработке Конституции США, а не то, как Верховный суд будет интерпретировать письменные письма Конституции США???

В конце концов, я живу в стране свободных, диких и дом храбрых. Будь смелым, будь свободным, будь диким - используй интерфейс. Если мои коллеги-программисты отказываются использовать эффективные и ленивые средства программирования, обязано ли я по золотому правилу снизить эффективность программирования, чтобы они соответствовали их? Возможно, я должен, но это не идеальная ситуация.