다음과 같은 예를 보았습니다.
public class MaxSeconds {
public static final int MAX_SECONDS = 25;
}
상수를 감싸서 Constant final 클래스를 선언하는 Constants 클래스를 가질 수 있다고 가정했습니다. 나는 실제로 Java가 전혀 없다는 것을 알고 있으며 이것이 상수를 만드는 가장 좋은 방법인지 궁금합니다.
다음과 같은 예를 보았습니다.
public class MaxSeconds {
public static final int MAX_SECONDS = 25;
}
상수를 감싸서 Constant final 클래스를 선언하는 Constants 클래스를 가질 수 있다고 가정했습니다. 나는 실제로 Java가 전혀 없다는 것을 알고 있으며 이것이 상수를 만드는 가장 좋은 방법인지 궁금합니다.
답변:
그것은 아마도 표준이라도 완벽하게 수용 가능합니다.
(public/private) static final TYPE NAME = VALUE;
여기서 TYPE
type NAME
은 공백의 밑줄이있는 모든 대문자의 이름이며 VALUE
상수 값입니다.
상수를 자체 클래스 또는 인터페이스에 두지 않는 것이 좋습니다.
참고로 : final로 선언되고 변경 가능한 변수는 계속 변경할 수 있습니다. 그러나 변수가 다른 객체를 가리킬 수는 없습니다.
예를 들면 다음과 같습니다.
public static final Point ORIGIN = new Point(0,0);
public static void main(String[] args){
ORIGIN.x = 3;
}
그것은 합법적이며 ORIGIN
(3, 0)의 지점이 될 것입니다.
단일 상수 클래스를 사용하지 않는 것이 좋습니다. 당시에는 좋은 생각처럼 보이지만 개발자가 상수를 문서화하지 않고 클래스가 500 개 이상의 상수를 포괄하도록 성장하면 (상대적으로 서로 관련이없는) (응용 프로그램의 완전히 다른 측면과 관련되어 있음) 일반적으로 상수 파일을 완전히 읽을 수 없게 만듭니다. 대신 :
상수를 유지하기 위해 인터페이스를 사용 하는 것은 나쁜 습관입니다 ( Josh Bloch가 명명 한 상수 인터페이스 패턴 ). Josh가 조언하는 내용은 다음과 같습니다.
상수가 기존 클래스 또는 인터페이스에 강력하게 연결되어 있으면 클래스 또는 인터페이스에 추가해야합니다. 예를 들어 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;
}
명명 규칙 정보 :
일반적으로 이러한 필드의 이름은 대문자로 구성되며 단어는 밑줄로 구분됩니다. 이러한 필드에는 기본 값 또는 변경 불가능한 객체에 대한 참조가 포함되어야합니다.
abstract
개인 생성자 대신 클래스에 표기법 을 사용하는 것이 좋습니다 .
abstract
프라이빗 생성자 대신 클래스 를 표시하면 인스턴스화를 완전히 막을 수 없습니다. 서브 클래스 화하고 서브 클래스를 인스턴스화 할 수 있기 때문입니다 (그렇게하는 것이 좋지는 않지만 가능합니다). @ToolmakerSteve 서브 클래스 생성자는 슈퍼 클래스의 (현재 프라이빗) 생성자를 호출해야하기 때문에 프라이빗 생성자가있는 클래스를 서브 클래 싱 할 수 없습니다 (적어도 큰 해킹이없는 경우는 아님). 따라서 표시 final
는 불필요합니다 (그러나 더 명시 적으로).
Effective 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'클래스를 변경하고 해당 클래스를 참조하는 다른 클래스에서 하드 재 컴파일을 수행하지 않으면 사용중인 이전 값과 새 값의 조합으로 마무리됩니다.
이를 상수로 생각하는 대신 구성 매개 변수로 생각하고 관리 할 클래스를 작성하십시오. 값이 최종 값이 아니고 getter 사용도 고려하십시오. 앞으로 이러한 매개 변수 중 일부가 실제로 사용자 나 관리자가 구성 할 수 있어야한다고 결정하면 훨씬 쉽게 수행 할 수 있습니다.
당신이 할 수있는 가장 큰 실수는 상수와 같은 일반적인 이름으로 불리는 전역 적으로 액세스 가능한 클래스를 만드는 것입니다. 이것은 단순히 쓰레기로 가득 차서 시스템의 어떤 부분이 이러한 상수를 사용하는지 알아낼 수있는 모든 능력을 잃습니다.
대신 상수는 "소유"하는 클래스로 이동해야합니다. TIMEOUT이라는 상수가 있습니까? 아마도 Communications () 또는 Connection () 클래스로 들어가야합니다. MAX_BAD_LOGINS_PER_HOUR? User ()로 이동합니다. 그리고 등등.
런타임에 "상수"를 정의 할 수 있지만 사용자가 쉽게 변경할 수없는 경우 Java .properties 파일이 사용됩니다. 이것들을 .jar에 패키징하고 Class resourceLoader로 참조 할 수 있습니다.
상수 대신 게터를 사용하는 것을 선호합니다. 이러한 게터는 예를 들어 상수 값을 반환 할 수 public int getMaxConnections() {return 10;}
있지만 상수가 필요한 것은 게터를 통과합니다.
한 가지 장점은 프로그램이 상수를 능가하는 경우 (구성 할 수 있어야 함) 게터가 상수를 반환하는 방법 만 변경할 수 있다는 것입니다.
다른 장점은 상수를 수정하기 위해 상수를 사용하는 모든 것을 다시 컴파일 할 필요가 없다는 것입니다. 정적 최종 필드를 참조하면 해당 상수의 값이이를 참조하는 모든 바이트 코드로 컴파일됩니다.
인터페이스를 사용하는 것이 좋은 방법이 아니라는 데 동의합니다. 이 패턴을 피하면 Bloch의 Effective Java 에 자체 항목 (# 18)이 있습니다.
상수 인터페이스 패턴에 대한 Bloch의 주장은 상수 사용이 구현 세부 사항이지만이를 사용하기 위해 인터페이스를 구현하면 내 보낸 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, static 및 final로 선언됩니다. 이유는 다음과 같습니다.
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
필드 :
로 Java 5 enum
:
TLDR : 상수를 찾는 가장 좋은 방법은 어디입니까?
대부분의 경우, 열거 방법은보다 아마도 더 미세 static final String/Integer
방법 개인적으로 나는 생각 static final String/Integer
방법은 우리가 열거 형을 사용하지 않도록 좋은 이유가있는 경우에만 사용되어야한다.
그리고 상수 값을 어디에서 선언해야하는지에 대한 아이디어는 상수 값 과 구체적이고 강력한 기능적 응집력을 소유하는 기존의 단일 클래스가 있는지 검색하는 것입니다. 그러한 클래스를 찾으면 상수 홀더로 사용해야합니다 . 그렇지 않으면 상수는 특정 클래스와 연관되지 않아야합니다.
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");
전송 된 값을 한 번에 확인한 경우에만 런타임시 오류가 발생합니다.
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 라이브러리에서 지수 및 파이 상수 값은 상수 선언 ( 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
, ... 정말 그들 중 아무도 열거를 유지하는 것이 더 적절한 것 같다.
모든 유형의 상수는 클래스 내에서 final
수정 자 속성을 갖는 멤버 변수 인 불변 속성을 만들어 선언 할 수 있습니다 . 일반적으로 static
및 public
수정 자도 제공됩니다.
public class OfficePrinter {
public static final String STATE = "Ready";
}
상수 값이 선택의 n- 튜플 (예 : 열거 )에서 선택을 나타내는 수많은 응용 프로그램이 있습니다 . 이 예에서는 가능한 할당 된 값을 제한하는 열거 형을 정의하도록 선택할 수 있습니다 (예 : 개선 된 type-safety ).
public class OfficePrinter {
public enum PrinterState { Ready, PCLoadLetter, OutOfToner, Offline };
public static final PrinterState STATE = PrinterState.Ready;
}
하나의 일반적인 상수 클래스는 나쁜 생각입니다. 상수는 가장 논리적으로 관련된 클래스와 함께 그룹화해야합니다.
모든 종류의 변수 (특히 열거 형)를 사용하는 대신 메서드를 사용하는 것이 좋습니다. 변수와 이름이 같은 메소드를 작성하고 변수에 지정한 값을 리턴하게하십시오. 이제 변수를 삭제하고 변수에 대한 모든 참조를 방금 만든 메소드에 대한 호출로 바꾸십시오. 상수가 일반적이기 때문에 클래스의 인스턴스를 만들 필요가 없어서 상수를 사용한다고 생각되면 상수 메서드를 클래스 메서드로 만듭니다.
차이점은 무엇입니까
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
이 상수가 필요한 곳이면 어디든 사용하십시오
. 둘 다 같다고 생각합니다.
한 단계 더 나아가려면 전역 적으로 사용되는 상수를 인터페이스에 배치하여 시스템 전체에서 사용할 수 있습니다. 예 :
public interface MyGlobalConstants {
public static final int TIMEOUT_IN_SECS = 25;
}
그러나 구현하지 마십시오. 정규화 된 클래스 이름을 통해 코드에서 직접 참조하십시오.
내가 사용하는 static final
상수를 선언하고 표기 명명 ALL_CAPS로 이동합니다. 모든 상수가 인터페이스로 묶여있는 실제 인스턴스가 몇 개 있습니다. 몇몇 게시물은 적절하지 않다고 지적했다. 주로 인터페이스가 아니기 때문이다. 인터페이스는 계약을 시행해야하며 관련없는 상수를 넣을 수있는 장소가되어서는 안됩니다. 상수 시맨틱이 특정 클래스에 속하지 않는 경우 (개인 생성자를 통해) 인스턴스화 할 수없는 클래스로 결합하는 것도 좋습니다 ( es). 나는 항상 가장 관련이있는 클래스에 상수를 넣습니다. 왜냐하면 의미가 있고 쉽게 유지할 수 있기 때문입니다.
열거 형은 값의 범위를 나타내는 좋은 선택이지만 절대 값 (예 : TIMEOUT = 100ms)에 중점을 둔 독립형 상수를 저장하는 경우 static final
접근 방식으로 갈 수 있습니다 .
나는 대부분의 말에 동의합니다. 상수 모음을 다룰 때 열거 형을 사용하는 것이 가장 좋습니다. 그러나 Android에서 프로그래밍하는 경우 더 나은 솔루션이 있습니다 : 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();
IntDef 주석은 간단한 방법으로 열거 형보다 우수하며 단순히 컴파일 타임 마커이기 때문에 공간이 훨씬 적게 걸립니다. 클래스가 아니며 자동 문자열 변환 속성도 없습니다.
기본 그라운드 제로 기본주의를 이해하지 않고 조슈아 블로흐를 인용 하는 것은 나쁜 습관과 끔찍한 혐오 행위 입니다.
나는 Joshua Bloch도 읽지 않았다.
성서 근본주의에서와 같이 모든 성서 법은 다음과 같이 요약 될 수 있습니다.
소프트웨어 엔지니어링의 근본주의는 다음과 같이 요약 될 수 있습니다.
또한 성서적 근본 주의자들 사이에서 강력하고 합리적인 견해가 도출된다
마찬가지로, 자신을 프로그래머로 존중하지 않고 기본에 대해 의문을 제기하지 않고 프로그래밍 전문가의 선언과 예언을 받아들이면 Joshua Bloch (및 기타)에 대한 인용과 의존은 의미가 없습니다. 그러므로, 당신은 실제로 동료 프로그래머를 존중하지 않을 것입니다.
소프트웨어 프로그래밍의 기본 법칙
이 종교 칙령은 근본적으로 효과적이고 책임감있는 프로그래밍 법에 따라 어떻게됩니까?
인터페이스 패턴 상수 ( https://en.wikipedia.org/wiki/Constant_interface ) 에 대한 wikipedia 기사를 읽고 인터페이스 패턴 상수 에 대해 멍청한 변명을합니다.
Whatif-No IDE? 누가 소프트웨어 프로그래머로서 IDE를 사용하지 않겠습니까? 우리 대부분은 IDE 사용을 피하면서 마치 초자연적 생존주의를 증명할 필요가없는 프로그래머입니다.
현재 범위 내에서 사용되지 않는 변수로 네임 스페이스를 오염 시키나요? 이 의견의 지지자가 될 수 있습니다
상수를 적용하기 위해 인터페이스를 사용하는 것은 인터페이스를 남용합니다. 그러한 지지자들은 나쁜 습관을 가지고있다
향후 인터페이스를 구현 된 클래스로 변환하는 것이 불가능하지는 않더라도 어렵습니다. 흠 .... 흠 ... ???
변명이 무엇이든, 기본적으로 효과적인 소프트웨어 엔지니어링에있어서 인터페이스 상수의 사용을 위임하거나 일반적으로 방해하지 않을 경우에는 유효한 변명이 없습니다.
미국 헌법을 만들었던 건국의 아버지들의 원래 의도와 정신 상태는 중요하지 않습니다. 우리는 건국의 아버지들의 원래 의도에 대해 토론 할 수 있었지만 제가 관심을 갖는 것은 미국 헌법의 서면 진술입니다. 그리고 미국 헌법의 문서화 된 근본 의도가 아닌 문학적 문학적 근본주의를 착취하는 것은 모든 미국 시민의 책임입니다.
마찬가지로 Java 플랫폼 및 프로그래밍 언어 창립자의 "원래"의도가 인터페이스에 어떤 영향을 미쳤는지 상관하지 않습니다. 내가 관심을 갖는 것은 Java 사양이 제공하는 효과적인 기능이며, 책임있는 소프트웨어 프로그래밍의 기본 법칙을 이행하는 데 도움이되도록 이러한 기능을 최대한 활용하려고합니다. "인터페이스의 의도를 위반하는"것으로 인식 되어도 상관 없습니다. 나는 Gosling이나 Bloch가 "자바를 사용하는 올바른 방법"에 대해 말하는 것을 신경 쓰지 않는다.
데이터 모델이 호스팅되거나 전송되는 방식은 중요하지 않습니다. 데이터 모델 정규화의 필요성과 프로세스를 이해하지 못하는 경우 인터페이스 또는 열거 형 또는 관계형 또는 비 SQL 등을 사용합니다.
먼저 일련의 프로세스의 데이터 모델을 정의하고 정규화해야합니다. 또한 일관된 데이터 모델이있는 경우에만 해당 구성 요소의 프로세스 흐름을 사용하여 기능적 동작을 정의하고 프로세스가 필드 또는 응용 프로그램 영역을 차단할 수 있습니다. 그런 다음에 만 각 기능 프로세스의 API를 정의 할 수 있습니다.
EF Codd가 제안한 데이터 정규화의 양상조차도 이제는 심각한 도전에 직면하고 있습니다. 예를 들어, 1NF에 대한 그의 진술은 특히 현대 데이터 서비스, 저장소 기술 및 전송의 출현에서 그의 진술의 나머지 부분과 같이 모호하고 잘못 정렬되어 지나치게 단순화 된 것으로 비난 받았다. IMO, EF Codd 문은 완전히 빠져 나와야하며 수학적으로 그럴듯한 새 문을 디자인해야합니다.
EF Codd의 눈에 띄는 결함과 효과적인 인간 이해에 대한 오정렬의 원인은 인간이 인식 할 수있는 다차원의 가변 치수 데이터가 일련의 단편적인 2 차원 맵핑을 통해 효율적으로 인식 될 수 있다는 그의 신념입니다.
EF Codd가 표현하지 못한 것.
각각의 코 히어 런트 데이터 모델 내에서, 이들은 순차적으로 단계적으로 데이터 모델 코 히어 런스를 달성하기위한 순서대로 정렬된다.
인터 서빙 컴포넌트 애플리케이션의 필드 또는 그리드에는 하나의 코 히어 런트 데이터 모델이 있어야하거나 데이터 모델 / 버전이 자신을 식별 할 수있는 수단이 있어야합니다.
이 평범한 질문보다 더 중요한 데이터 정규화 문제가 있습니다. 이러한 문제를 해결하지 못하면 인터페이스 상수로 인해 발생하는 혼동은 상대적으로 아무것도 아닙니다. 제로.
그런 다음 데이터 모델 정규화에서 구성 요소를 특성, 계약 인터페이스 상수로 변수로 결정합니다.
그런 다음 값 삽입, 속성 구성 자리 표시, 인터페이스, 최종 문자열 등을 결정합니다.
인터페이스 상수에 대해보다 쉽게 지시 할 수있는 구성 요소를 찾아야한다는 구실을 사용해야하는 경우 데이터 모델 정규화를 실행하지 않는 습관이 나빠질 수 있습니다.
아마도 데이터 모델을 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-motivated 런타임 스와핑에 복잡성을 제공합니까? Osgi는 프로그래머가 나쁜 습관을 계속 유지할 수있는 매우 효율적인 수단입니다. osgi보다 더 나은 대안이 있습니다.
아니면 왜 안됩니까? 비공개 상수가 공개 된 계약으로 유출되지 않습니다. 상수를 검색 할 필요가없고 "private final String"을 반복적으로 입력하기에는 너무 게으 르기 때문에 모든 개인 상수는 "Constants"라는 개인 인터페이스로 그룹화해야합니다.
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;
}
}
고려해야 할 인터페이스 상수의 유일한 문제는 인터페이스가 구현 될 때입니다.
이것이 인터페이스의 "원래 의도"가 아닙니까? 내가 대법원이 미국 헌법의 서면 서한을 해석하는 방법보다는 미국 헌법을 만드는 데있어 건국의 아버지들의 "원래 의도"에 관심이있는 것처럼 ???
결국, 나는 자유의 땅, 용감한 집과 야생의 집에서 산다. 용감하고, 자유롭고, 강렬하다-인터페이스를 사용하십시오. 동료 프로그래머가 효율적이고 게으른 프로그래밍 수단을 사용하지 않으면 프로그래밍 규칙을 따라야하는 프로그래밍 효율을 낮추는 황금률이 적용됩니까? 아마도 내가해야하지만 이상적인 상황은 아닙니다.