Как лучше всего реализовать константы в Java?[закрыто]

StackOverflow https://stackoverflow.com/questions/66066

  •  09-06-2019
  •  | 
  •  

Вопрос

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

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

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

Это было полезно?

Решение

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

(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).

Другие советы

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

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

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

Если константы тесно связаны с существующим классом или интерфейсом, вы должны добавить их в класс или интерфейс.Например, все в штучных численных примитивных классах, такие как целое число и двойные, экспортные константы 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;
}

О соглашении об именах:

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

В «Эффективной Java» (2-е издание) для констант рекомендуется использовать перечисления вместо статических целых чисел.

Здесь есть хорошая статья о перечислениях в Java:http://java.sun.com/j2se/1.5.0/docs/guide/language/enums.html

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

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

С ответом:

В любое время, когда вам нужен фиксированный набор констант

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

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

public class NeddsConstant implements MyConstants {

}

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

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

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 чтобы получить константу.Как по мне, это выглядит более "объектно-ориентировано".

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Если ваши константы можно хорошо смоделировать как перечисление, рассмотрите перечисление структура доступна в версии 1.5 или новее.

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

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

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

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

Существует определенное количество мнений, позволяющих ответить на этот вопрос.Начнем с того, что константы в 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

Как лучше всего реализовать константы в Java?

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

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

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


Для упрощения у нас есть в целом 4 действительных подхода..

С static final String/Integer поле :

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

С Java 5 enum :

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

TLDR:Каков наилучший способ и где найти константы?

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


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

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

Например, ниже две константы, определенные в классе как 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");

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

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

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

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 значения экспоненты и константы числа пи объявляются в классе, который объявляет не только объявления констант (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 enum не объявлен в определенном классе, поскольку на самом деле не существует одного и только одного конкретного класса JDK, который выглядит наиболее интуитивно понятным для его хранения:

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

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

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

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

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

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

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

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

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

В чем разница

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 везде, где нам нужна эта константа.Я думаю, что оба одинаковы.

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

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

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

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

ИМХО, для констант 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 }


}

Один из способов сделать это — создать «глобальный» класс с постоянными значениями и выполнить статический импорт в классы, которым требуется доступ к константе.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Фундаментальные законы программирования

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Даже аспекты нормализации данных, предложенные Э. Ф. Коддом, сейчас подвергаются серьезным и серьезным проблемам.напримерего заявление о 1NF подверглось критике как двусмысленное, несогласованное и чрезмерно упрощенное, как и остальные его заявления, особенно с появлением современных услуг передачи данных, технологий репо и передачи данных.ИМХО, от утверждений Э. Ф. Кодда следует полностью отказаться и разработать новый набор более математически правдоподобных утверждений.

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

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

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

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

  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-программист, меня не волнует структура jar.

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

Или почему не это?Утечки частных констант в опубликованный контракт не происходит.Все частные константы должны быть сгруппированы в частный интерфейс с именем «Константы», потому что я не хочу искать константы, и мне лень повторно вводить «частную окончательную строку».

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top