programing

Java에서 상수를 구현하는 가장 좋은 방법은 무엇입니까?

prostudy 2022. 8. 28. 12:00
반응형

Java에서 상수를 구현하는 가장 좋은 방법은 무엇입니까?

나는 다음과 같은 예를 본 적이 있다.

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

상수를 랩할 상수 클래스가 있다고 가정하고 정적 최종이라고 선언합니다.저는 Java를 전혀 모르기 때문에 이것이 상수를 만드는 가장 좋은 방법인지 궁금합니다.

그것은 완벽하게 받아들여질 수 있다, 아마도 기준일 것이다.

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

서 ''는TYPENAME이 있는 이며, '스페이스'는 '스페이스'입니다.VALUE수수값값값값다다

자신의 클래스나 인터페이스에 상수를 넣지 않는 것이 좋습니다.

참고 사항으로:최종으로 선언되어 변경 가능한 변수는 변경할 수 있지만 변수는 다른 개체를 가리킬 수 없습니다.

예를 들어 다음과 같습니다.

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

public static void main(String[] args){

    ORIGIN.x = 3;

}

이고 건건합 that that that that that that thatORIGIN3, 0에서.

단일 상수 클래스는 사용하지 말 것을 강력히 권고합니다.그 시점에서는 좋은 생각인 것 같지만, 개발자가 상수를 문서화하는 것을 거부하고 클래스가 서로 전혀 관련이 없는 500개 이상의 상수를 포함하게 되면(어플리케이션의 전혀 다른 측면과 관련됨), 일반적으로 상수 파일은 완전히 읽을 수 없게 됩니다.대신:

  • Java 5+에 액세스할 수 있는 경우 enum을 사용하여 응용 프로그램 영역의 특정 상수를 정의합니다.응용 프로그램 영역의 모든 부분은 이러한 상수에 대해 상수 값이 아닌 에넘을 참조해야 합니다.클래스를 선언하는 방법과 유사한 열거형을 선언할 수 있습니다.Enum은 아마도 Java 5+의 가장 유용한 기능일 것입니다.
  • 특정 클래스 또는 해당 하위 클래스 중 하나에 대해서만 유효한 상수가 있는 경우 해당 상수를 protected 또는 public으로 선언하고 계층 내 최상위 클래스에 배치합니다.이렇게 하면 서브클래스는 이러한 상수 값에 액세스할 수 있습니다(다른 클래스가 퍼블릭을 통해 액세스하면 해당 상수는 특정 클래스에만 유효한 것이 아닙니다).즉, 이 상수를 사용하는 외부 클래스가 상수를 포함하는 클래스와 너무 긴밀하게 결합될 수 있습니다.)
  • 동작이 정의되어 있지만 반환된 값 또는 인수 값이 특정해야 하는 인터페이스가 있는 경우 다른 구현자가 해당 인터페이스에 접근할 수 있도록 상수를 정의하는 것이 완전히 허용됩니다.다만, 상수를 유지하기 위해서만 인터페이스를 작성하지 말아 주세요.상수를 유지하기 위해서만 작성된 클래스와 같은 상태가 될 수 있습니다.

인터페이스를 상수(Josh Bloch에 의해 일정한 인터페이스 패턴으로 명명됨)만을 유지하기 위해 사용하는 것은 BAD PRACTICES입니다.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;
}

명명 규칙에 대해:

관례상 이러한 필드에는 대문자로 구성된 이름이 있으며 단어는 밑줄로 구분됩니다.이러한 필드는 원시 값 또는 불변의 객체에 대한 참조를 포함하는 것이 중요합니다.

Effective Java(제2판)에서는 정적인 int 대신 enum을 사용하는 것이 좋습니다.

자바어 enums에 대한 좋은 글이 여기 있습니다.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' 클래스를 변경하고 해당 클래스를 참조하는 다른 클래스에서 하드 재컴파일을 수행하지 않으면 이전 값과 새 값의 조합이 사용됩니다.

이들을 상수로 간주하지 않고 설정 파라미터로 간주하고 클래스를 생성하여 관리합니다.값은 최종값이 아니며, getters를 사용하는 것도 고려합니다.앞으로는 이들 파라미터 중 일부를 사용자 또는 관리자가 실제로 설정할 필요가 있다고 판단하면 훨씬 쉽게 설정할 수 있게 됩니다.

가장 큰 실수는 Constant와 같은 일반 이름을 사용하여 글로벌하게 액세스할 수 있는 클래스를 만드는 것입니다.이것은 단순히 가비지로 가득 차 버리기 때문에 시스템에서 이러한 상수를 사용하는 부분을 파악할 수 없게 됩니다.

대신 상수는 해당 상수를 "소유"하는 클래스로 이동해야 합니다.타임아웃이라는 상수가 있나요?Communications() 또는 Connection() 클래스로 이동합니다.MAX_BAD_로그인_PER_HOUR?User()로 이동합니다.기타 등등.

실행 시 "정수"를 정의할 수 있지만 사용자가 쉽게 변경할 수 없는 경우 Java .properties 파일을 사용할 수 있습니다..jars에 패키지화하여 클래스 resourceLoader에서 참조할 수 있습니다.

그게 옳은 길이에요.

일반적으로 상수는 검색할 수 없기 때문에 별도의 "상수" 클래스에 보관되지 않습니다.상수가 현재 클래스와 관련이 있는 경우 해당 상수를 유지하면 다음 개발자에게 도움이 됩니다.

열거는 어때?

겟터 값을할 수 "getter"는 "getter"는 "getter는 "getter"를 반환할 수 있습니다.public int getMaxConnections() {return 10;}단, 상수가 필요한 것은 모두 게터를 통과합니다.

한 가지 이점은 프로그램이 상수를 초과할 경우(설정할 필요가 있음을 알게 되면) getter가 상수를 반환하는 방법을 변경할 수 있다는 것입니다.

또 다른 장점은 상수를 수정하기 위해 상수를 사용하는 모든 것을 다시 컴파일할 필요가 없다는 것입니다.정적 최종 필드를 참조할 경우 해당 상수의 값은 해당 필드를 참조하는 모든 바이트 코드로 컴파일됩니다.

인터페이스를 사용하는 것이 바람직한 방법이 아니라는 것에 동의합니다.이 패턴을 회피하는 것은 Bloch의 Effective Java에 독자적인 아이템(#18)도 있습니다.

Bloch가 주장하는 인터페이스 패턴에 대한 주장은 상수 사용은 구현 세부 사항이지만, 상수를 사용하기 위한 인터페이스를 구현하면 해당 구현 세부 사항이 내보낸 API에 노출된다는 것입니다.

public|private static final TYPE NAME = VALUE;pattern을 입니다.개인적으로, 나는 모든 상수를 수용하기 위해 별도의 수업을 만드는 것을 피하는 것이 좋다고 생각하지만, 나는 개인적인 취향과 스타일 외에 이것을 하지 말아야 할 이유를 본 적이 없다.

상수를 열거형으로 적절하게 모델링할 수 있는 경우 1.5 이후에 사용할 수 있는 열거 구조를 고려하십시오.

1.5 이전 버전을 사용하는 경우에도 일반 Java 클래스를 사용하여 type safe 열거를 수행할 수 있습니다.(자세한 내용은 이 사이트를 참조하십시오).

위의 코멘트에 근거해, 다음과 같은 방법으로, 구식의 글로벌 상수 클래스(공중 정적 최종 변수 포함)를 열거형 등가로 변경하는 것이 좋은 어프로치라고 생각합니다.

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

단순히 인터페이스가 일반적으로 구현될 것으로 예상되기 때문에 CONTUST 접근자/객체에 인터페이스를 사용하지 않습니다.이상하지 않을까요?

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) variant는 상수를 선언하는 전용 클래스를 만듭니다.

★★★★★★★★★★★★★★★★ Java 5 enum:

  • 2) 관련 목적 클래스(네스트 클래스)에서 열거를 선언합니다.
  • 2) 스탠드아론 클래스로 Enum을 만듭니다(자체 클래스 파일에 정의되어 있습니다.

TLDR : 어떤 것이 가장 좋은 방법이고 상수를 찾는 위치입니까?

대부분의 경우, 열거 방법은 아마도 방법보다 더 미세할 것이고 개인적으로 나는 그 방법이 그 방법이라고 생각한다.static final String/Integerenum을 하지 않는 가 있는 해야 합니다.
그리고 상수 값을 선언해야 하는 위치에 대해서는 특정하고 강력한 함수적 응집력을 가진 기존 클래스가 하나라도 존재하는지 여부를 조사하는 것입니다. 이러한 클래스가 발견되면 상수 홀더로 사용해야 합니다.그렇지 않은 경우 상수는 특정 클래스에 관련지을 수 없습니다.


static final Stringstatic final Integervs 대 enum

enums en en en en en en en en en en en en en en en 。
는 enums보다 훨씬 하다.String ★★★★★★★★★★★★★★★★★」Integer일정한 필드
이치노enum을 매개 변수로 사용하는 메서드를 정의하는 경우 enum 클래스(또는 null)에 정의된 enum 값만 전달할 수 있습니다.
하면 String " Integer"에서 가 아니더라도 할 수 .static final Stringstatic 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은 enum 의 enum 값입니다.

예를 들어 enum 클래스에 정의되어 있는2개의 값이 있습니다(따라서, 즉시 사용할 수 있습니다.

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)만이되지 않는 클래스에서 됩니다('JDK'는 'pi'를 '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 변종) 방법이 더 직관적으로 보입니다.
일반적으로 상수를 조작하는 클래스가1개로 선언되어 있는 경우, 상수를 조작하는 클래스가 3개 또는 4개 있고, 이들 클래스 중 상수 값을 호스트하는 것이 다른 클래스보다 자연스러운 것은 없는 것 같습니다.
여기서 상수 값만 유지하도록 사용자 정의 클래스를 정의하는 것은 의미가 있습니다.
를 들어 JDK는 " " " " 입니다.java.util.concurrent.TimeUnit이 클래스는하는 가장 때문입니다.enum은 enum으로 표시됩니다.이는 JDK 고유 클래스가 실제로1개밖에 없기 때문입니다.

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-tuple(예: 열거)에서 선택을 나타내는 수많은 애플리케이션이 있다.이 예에서는 할당 가능한 값을 제한하는 열거형 유형을 정의하도록 선택할 수 있습니다(예: 개선된 유형 안전).

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

단일 범용 상수 클래스는 좋지 않습니다.상수는 가장 논리적으로 관련된 클래스와 함께 그룹화해야 합니다.

변수(특히 enum)를 사용하는 대신 방법을 사용하는 것이 좋습니다.변수와 이름이 같은 메서드를 만들고 변수에 할당한 값을 반환하도록 합니다.이제 변수를 삭제하고 해당 변수에 대한 모든 참조를 방금 작성한 메서드에 대한 호출로 바꿉니다.상수만 사용하기 위해 클래스의 인스턴스를 만들 필요가 없을 정도로 상수가 일반적이라고 생각되면 상수 메서드를 클래스 메서드로 만듭니다.

FWIW의 타임아웃(초단위) 값은 상수가 아닌 설정(스프링과 같이 속성 파일에서 읽거나 주입을 통해 읽음)이어야 합니다.

차이점은 무엇입니까?

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

and and를 합니다.MyGlobalConstants.TIMEOUT_IN_SECS이 상수가 필요한 곳이면 어디든 갈 수 있어요.이 노래예요.

(케이스를 제외하고) 클래스는 상수...라고는 할 수 없습니다.모든 상수가 존재할 "설정", "값" 또는 "상수" 클래스가 적어도 한 개 이상 있을 것입니다.많은 경우 논리 상수 클래스(UserSettings, AppSettings 등)로 그룹화합니다.

한 걸음 더 나아가 글로벌하게 사용되는 상수를 인터페이스 내에 배치하여 시스템 전체에서 사용할 수 있도록 할 수 있습니다.예.

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

하지만 그 후에는 구현하지 마십시오.정규 클래스명을 통해 코드로 직접 참조해 주세요.

상수의 경우 Enum이 IMHO를 선택하는 것이 좋습니다.여기 예가 있습니다.

퍼블릭 클래스 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 }


}

이 방법 중 하나는 상수 값을 사용하여 'Global' 클래스를 만들고 상수 액세스 권한이 필요한 클래스에서 정적 가져오기를 수행하는 것입니다.

static final제 취향입니다. ★★★★★★★★★★…enum네, 네, 네, 네.

용 i i i i를 쓴다.static finalALL_CAPS를 사용합니다.모든 상수가 하나의 인터페이스로 묶이는 실제 사례를 많이 봐왔습니다.몇몇 게시물에서는 이를 나쁜 관행이라고 하는데, 그 주된 이유는 인터페이스의 용도가 아니기 때문입니다.인터페이스는 계약을 시행해야 하며 관련 없는 상수를 삽입하는 장소가 되어서는 안 됩니다.상수 시멘틱스가 특정 클래스에 속하지 않는 경우 (프라이빗 컨스트럭터를 통해) 인스턴스화할 수 없는 클래스에 합치는 것도 좋습니다.저는 항상 가장 관련이 있는 수업에 상수를 둡니다. 왜냐하면 그것은 타당하고 쉽게 유지보수가 가능하기 때문입니다.

「TIMOUT = 100 」로 할 수 .static final★★★★★★ 。

대부분의 의견에 동의합니다. 상수 집합을 다룰 때는 enum을 사용하는 것이 가장 좋습니다.그러나 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 주석은 간단한 방법으로 enums보다 우수하며, 단순히 컴파일 시간 마커이기 때문에 훨씬 적은 공간을 차지합니다.이것은 클래스가 아니며 자동 문자열 변환 속성도 없습니다.

기본적인 제로 근본주의를 이해하지 못한 채 조슈아 블로크를 인용하는 것은 나쁜 습관이고 매우 짜증나는 관행이다.

조슈아 블록도 못 읽어서

  • 그는 형편없는 프로그래머이다.
  • 아니면 지금까지 내가 그를 인용한 사람들(조슈아는 소년의 이름일 것이다)은 단순히 그들의 소프트웨어 종교적 면죄부를 정당화하기 위해 그의 자료를 종교 대본으로 사용하고 있을 뿐이다.

성경 원리주의에서와 같이 모든 성경 법칙은 요약될 수 있다.

  • 온 마음과 온 마음을 다해 근본적인 정체성을 사랑하라.
  • 네 이웃을 네 자신처럼 사랑하라.

마찬가지로 소프트웨어 엔지니어링 근본주의는 다음과 같이 요약할 수 있습니다.

  • 프로그래밍의 힘과 정신을 다해 그라운드 제로 펀더멘털에 전념하다
  • 동료 프로그래머의 우수성을 위해 헌신할 수 있습니다.

또한 성서 근본주의자들 사이에서는 강력하고 합리적인 결과가 도출된다.

  • 먼저 자신을 사랑하라.자신을 별로 사랑하지 않으면 이웃을 자기 자신처럼 사랑한다는 개념은 중요하지 않다.왜냐하면 '얼마나 자신을 사랑하는가'는 다른 사람을 사랑하는 기준선이 되기 때문이다.

마찬가지로, 만약 당신이 자신을 프로그래머로 존중하지 않고, 근본적인 것에 의문을 제기하지 않고 단지 몇몇 프로그래밍 전문가들의 선언과 예언을 받아들인다면, 당신의 인용문이나 조슈아 블로흐에 대한 의존은 무의미하다.따라서 당신은 동료 프로그래머를 존중하지 않을 것입니다.

소프트웨어 프로그래밍의 기본 법칙

  • 게으름은 훌륭한 프로그래머의 미덕이다.
  • 당신은 당신의 프로그래밍 생활을 최대한 쉽고 게으르게 만들어야 한다. 따라서 가능한 한 효과적이다.
  • 프로그래밍의 결과와 내장을 가능한 한 쉽고 게으르게 만들어 당신과 함께 일하고 프로그래밍 내장을 집어들고 있는 프로그래머들에게 최대한 효과적으로 만들어야 합니다.

인터페이스 패턴의 상수는 나쁜 습관입니다.

근본적으로 효과적이고 책임감 있는 프로그래밍의 어떤 법칙에 따라 이 종교 교령이 적용되는가?

인터페이스 패턴 상수(https://en.wikipedia.org/wiki/Constant_interface), 및 인터페이스 패턴 상수에 대한 바보 같은 변명)에 대한 Wikipedia 기사를 읽어보시기 바랍니다.

  • IDE 없음소프트웨어 프로그래머로서 IDE를 사용하지 않는 사람이 도대체 있을까요?우리 대부분은 IDE의 사용을 피하면서 남성적인 생존주의가 있다는 것을 증명하지 않아도 되는 프로그래머들이다.

    • 또한 - IDE가 필요 없는 수단으로 마이크로 기능 프로그래밍의 두 번째 지지자를 기다립니다.데이터 모델 정규화에 대한 설명을 읽을 때까지 기다리십시오.
  • 현재 범위 내에서 사용되지 않는 변수로 네임스페이스를 오염하시겠습니까?이 의견의 지지자일 수도 있다.

    • 데이터 모델의 정규화를 인식하고 있지 않으며, 그 필요성도 인식하고 있지 않다.
  • 상수를 적용하기 위해 인터페이스를 사용하는 것은 인터페이스를 남용하는 것입니다.그러한 지지자들은 나쁜 습관을 가지고 있다.

    • 계약으로 취급해야 한다는 것을 알지 못한다.또한 인터페이스는 계약에 대한 컴플라이언스를 적용하거나 예상하는 데 사용됩니다.
  • 향후, 인터페이스를 실장 클래스로 변환하는 것은 불가능하지 않습니다.하하…음... ?--

    • 왜 당신은 당신의 지속적인 생계처럼 프로그래밍에 종사하고 싶어 합니까?IOW, 왜 그런 앰브에 전념하는 거죠?IVALENT와 나쁜 프로그래밍 습관?

어떤 핑계든 근본적으로 효과적인 소프트웨어 엔지니어링에 관해서는 인터페이스 상수의 사용을 위임하거나 일반적으로 권장하지 않는 유효한 핑계는 없습니다.

미국 헌법을 만든 건국의 아버지들의 본래 의도와 정신 상태가 어떠했는지는 중요하지 않다.우리는 건국의 아버지들의 본래 의도에 대해 토론할 수 있지만 내가 신경 쓰는 것은 미국 헌법의 성명에 관한 것이다.그리고 미국 헌법의 불문건립 취지가 아닌 성문학적 근본주의를 이용하는 것은 모든 미국 시민의 책임이다.

마찬가지로, 자바 플랫폼과 프로그래밍 언어의 창시자들이 인터페이스에 어떤 "원래" 의도를 가지고 있었는지는 상관하지 않습니다.중요한 것은 Java 사양이 제공하는 효과적인 기능이며, 이러한 기능을 최대한 활용하여 책임감 있는 소프트웨어 프로그래밍의 기본 법칙을 충족시킬 것입니다.「인터페이스의 의도를 위반한다」라고 인식되어도 상관없습니다.Gosling이나 Bloch가 말하는 "Java를 사용하는 올바른 방법"은 그들이 말하는 것이 효과적인 기본을 달성하려는 나의 요구를 위반하지 않는 한 나는 상관하지 않는다.

기본은 데이터 모델의 정규화입니다.

데이터 모델의 호스트 방식이나 전송 방식은 중요하지 않습니다.인터페이스, Enum 또는 Whatevernot을 사용하는지 여부에 관계없이 데이터 모델 정규화의 필요성과 프로세스를 이해하지 못하는 경우 관계형 또는 비SQL을 사용합니다.

먼저 일련의 프로세스 데이터 모델을 정의하고 정규화해야 합니다.또한 일관된 데이터 모델이 있는 경우에만 해당 구성요소의 프로세스 흐름을 사용하여 기능 동작을 정의하고 애플리케이션 필드 또는 영역을 프로세스 블록할 수 있습니다.그래야 각 기능 프로세스의 API를 정의할 수 있습니다.

EF Codd가 제안한 데이터 정규화 측면도 현재 심각한 도전을 받고 있으며, 예를 들어 1NF에 대한 그의 발언은 모호하고 잘못 정렬되었으며 지나치게 단순하다는 비판을 받고 있습니다. 특히 현대 데이터 서비스, 리포 기술 및 전송의 등장에 대한 그의 진술은 더욱 그렇습니다.IMO, EF Codd 문장은 완전히 폐기하고 수학적으로 보다 그럴듯한 문장의 새로운 세트를 설계해야 합니다.

EF Codd의 명백한 결점은 인간이 인식할 수 있는 다차원, 가변 차원 데이터를 단편적인 2차원 매핑을 통해 효율적으로 인식할 수 있다는 믿음입니다.

데이터 정규화의 기본

EF Codd가 표현하지 못한 것.

각 일관성 있는 데이터 모델 내에서 달성해야 할 데이터 모델 일관성의 순차적 단계별 순서입니다.

  1. 「유니티」아이덴티티
    • 각 데이터 구성요소의 세분성을 설계합니다. 세분성은 구성요소의 각 인스턴스를 고유하게 식별하고 검색할 수 있는 수준입니다.
    • 인스턴스 에일리어싱이 없습니다. 즉, 식별이 구성요소의 인스턴스를 두 개 이상 생성하는 방법은 존재하지 않습니다.
  2. 인스턴스 크로스톡이 없습니다.컴포넌트의 인스턴스 식별에 기여하기 위해 컴포넌트의 다른 인스턴스를 하나 이상 사용할 필요는 없습니다.
  3. 데이터 컴포넌트/치수의 통일성과 동일성.
    • 컴포넌트 에일리어스 해제 유무구성 요소/치수를 고유하게 식별할 수 있는 하나의 정의가 있어야 합니다.컴포넌트의 주요 정의
    • 1차 정의가 의도된 구성요소의 일부가 아닌 하위 치수 또는 부재 구성요소를 노출시키지 않는 경우
  4. 컴포넌트 거래의 독자적인 수단.구성 요소에 대한 이러한 구성 요소 별칭 해제 정의가 하나뿐 아니라 하나만 있어야 합니다.
  5. 구성요소의 계층적 관계에서 상위 구성요소를 식별하기 위한 정의 인터페이스 또는 계약이 하나뿐입니다.
  6. 컴포넌트 크로스톡이 없습니다.구성요소의 확정적 식별에 기여하기 위해 다른 구성요소의 구성원을 사용할 필요는 없다.
    • 이러한 부모-자녀 관계에서 부모의 식별 정의는 자녀 구성 요소 집합의 일부에 의존해서는 안 된다.부모 아이덴티티의 구성원 구성 요소는 자녀의 일부 또는 전부를 참조하지 않고 완전한 자녀 아이덴티티여야 합니다.
  7. 데이터 모델의 바이모달 또는 멀티모달 어피아란스를 프리엠프션합니다.
    • 컴포넌트의 후보 정의가 2개 존재하는 경우, 2개의 서로 다른 데이터 모델이 하나로 혼재하고 있음을 알 수 있습니다.즉, 데이터 모델 레벨 또는 필드 레벨에서 일관성이 없습니다.
    • 애플리케이션 분야에서는 하나의 데이터 모델만 일관성 있게 사용해야 합니다.
  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

이게 항아리 파일 내용을 헷갈리게 하는 건가요?자바 프로그래머로서 나는 그 항아리 구조에 신경 쓰지 않는다.

이것은 osgi에 의한 런타임 스와핑의 복잡성을 나타냅니다.Osgi는 프로그래머들이 나쁜 습관을 계속 유지하도록 하는 매우 효율적인 수단이다.osgi보다 더 좋은 대안이 있다.

아니면 왜 안 돼?비공개 상수가 공개된 계약으로 유출되는 일은 없습니다.모든 개인 상수는 "Constants"라는 이름의 개인 인터페이스로 그룹화해야 합니다. 왜냐하면 저는 상수를 검색할 필요가 없고 "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;
  }
}

고려할 가치가 있는 인터페이스 상수의 유일한 문제는 인터페이스가 구현되었을 때입니다.

이것은 인터페이스의 「원래의 의도」가 아닙니다.대법원이 미국 헌법의 서한을 어떻게 해석하느냐가 아니라 미국 헌법을 제정하는 데 있어서 창시자들의 '원초적 의도'에 관심이 있는 것처럼--

결국, 나는 자유의 땅, 야생의 땅, 그리고 용감한 자들의 집에 살고 있다.용감해지고, 자유로워지고, 거칠어져야 합니다.인터페이스를 사용하세요.동료 프로그래머들이 효율적이고 게으른 프로그래밍 방법을 사용하지 않을 경우, 나는 그들의 프로그래밍에 맞추기 위해 프로그래밍 효율을 떨어뜨려야 하는 황금률에 의해 강요당할까?그래야 할 것 같은데, 그건 이상적인 상황이 아니에요.

언급URL : https://stackoverflow.com/questions/66066/what-is-the-best-way-to-implement-constants-in-java

반응형