it-source

인터페이스 상수의 용도는 무엇입니까?

criticalcode 2023. 1. 23. 10:10
반응형

인터페이스 상수의 용도는 무엇입니까?

Java를 배우고 있는데 인터페이스에 퍼블릭 스태틱 및 최종 필드가 있을 수 있다는 것을 알게 되었습니다.나는 지금까지 이런 예를 본 적이 없다.이러한 인터페이스 상수의 사용 예에는 어떤 것이 있으며 Java Standard Library에서 확인할 수 있습니까?

스태틱 멤버를 인터페이스에 배치하는(및 그 인터페이스를 실장하는) 것은 나쁜 관행이며, Constant Interface Antiattern이라는 이름도 있습니다.「Effective Java, Item 17:」을 참조해 주세요.

인터페이스 패턴이 일정하면 인터페이스가 제대로 사용되지 않습니다.클래스가 내부적으로 일부 상수를 사용하는 것은 구현 세부 사항입니다.지속적인 인터페이스를 구현하면 이 구현 세부 정보가 클래스의 내보낸 API로 유출됩니다.클래스가 일정한 인터페이스를 구현하는 것은 클래스 사용자에게 중요하지 않습니다.사실, 그것은 그들을 혼란스럽게 할 수도 있다.더 나쁜 것은 이것이 약속임을 나타냅니다.앞으로 출시될 릴리스에서 클래스가 상수를 사용할 필요가 없도록 변경된 경우에도 바이너리 호환성을 확보하기 위해 인터페이스를 구현해야 합니다.비최종 클래스가 일정한 인터페이스를 실장하고 있는 경우, 그 서브 클래스의 모든 네임스페이스는 인터페이스의 상수에 의해 오염됩니다.

Java와 몇 일정한 .java.io.ObjectStreamConstants이러한 인터페이스는, 이상이라고 간주해, 에뮬레이트 하지 말아 주세요.

지속적인 인터페이스의 함정을 피하려면(사용자가 이를 구현하는 것을 막을 수 없기 때문에), 개인 컨스트럭터를 가진 적절한 클래스를 선호해야 합니다(Wikipedia에서 차용한 예).

public final class Constants {

    private Constants() {
        // restrict instantiation
    }

    public static final double PI = 3.14159;
    public static final double PLANCK_CONSTANT = 6.62606896e-34;
}

완전한 수식 없이(즉, 클래스 이름을 접두사로 붙이지 않고) 상수에 액세스하려면 (Java 5 이후) 정적 가져오기를 사용합니다.

import static Constants.PLANCK_CONSTANT;
import static Constants.PI;

public class Calculations {

    public double getReducedPlanckConstant() {
        return PLANCK_CONSTANT / (2 * PI);
    }
}

"인터페이스 패턴이 일정하면 인터페이스가 제대로 사용되지 않습니다."

누가 이 가설을 지어냈든, 아무리 권위자라 해도, 나쁜 습관과 관행을 효율적으로 실행할 필요성에 근거해 지어낸 것이다.이 가설은 불량 소프트웨어 설계 습관의 타당성을 촉진하는 데 기초하고 있습니다.

나는 그 가설에 대한 반론을 여기에 썼다.Java에서 상수를 구현하는 가장 좋은 방법은 무엇입니까?이 가설의 근거 없는 것을 설명하고 있다.

10년 동안 그 질문은 내가 이 가설을 정당화하는 이유를 게시한 후 2시간 이내에 종결될 때까지 열려있었고, 따라서 이 잘못된 가설을 대단히 고수하는 사람들에 의해 토론에 대한 내키지 않는 것이 드러났다.

이것들은 내가 그 가설에 반대해서 표현한 것이다.

  • 이 가설을 유지하는 근거는 나쁜 소프트웨어 습관과 방법론의 영향에 대처하기 위한 방법과 RESTRICTIVE 규칙의 필요성이다.

  • 인터페이스 패턴이 항상 있는 것은, 인터페이스의 부적절한 사용이다」라고 하는 의견의 지지자는, 그러한 나쁜 습관이나 관행의 영향에 대처하는 것이 필요하기 때문에 생기는 이유 이외의 이유를 제시할 수 없습니다.

  • 근본적인 문제를 해결하다.

  • 그리고 Java 언어 구조의 모든 언어 기능을 자신의 편의에 맞게 활용하고 활용하는 것은 어떨까요?재킷은 필요 없습니다.왜 더 효과적인 라이프스타일을 차별하고 유죄를 입증하기 위해 당신의 비효율적인 라이프스타일을 차단하기 위한 규칙을 만드나요?

근본적인 문제

정보 조직입니다.프로세스를 매개하는 정보 및 그 정보의 동작을 이른바 비즈니스 규칙과 함께 먼저 이해한 후 프로세스에 대한 솔루션을 엔지니어링하거나 보완해야 합니다.이러한 정보 정리 방법을 수십 년 전에는 데이터 정규화라고 불렀습니다.

솔루션 구성요소의 세분화 및 모듈화와 정보 구성요소의 세분화 및 모듈화를 맞추는 것이 최적의 전략이기 때문에 솔루션의 엔지니어링만이 가능합니다.

정보를 정리하는 데는 두세 가지 중요한 장애물이 있습니다.

  1. 데이터 모델의 「정규화」의 필요성에 대한 인식의 결여.

  2. 데이터 정규화에 대한 EF Codd의 진술은 결함이 있고 결함이 있으며 모호합니다.

  3. 신속한 변화를 위한 엔지니어링으로 가장한 최신 유행은 모듈 구성을 사전에 계획하거나 조건화해서는 안 된다는 잘못된 개념입니다. 왜냐하면 모듈 구성에 따라 리팩터를 적용할 수 있기 때문입니다.향후의 발견에 방해받지 않고 리팩터링과 지속적인 변화를 빌미로 삼는다.프로세스 정보의 행동에 대한 본질적인 발견은 이익과 자산화를 지연시키기 위해 회계 속임수를 사용하는 것이기 때문에 필수적인 지식과 그 처리는 현재 필요하지 않다고 간주됩니다.

인터페이스 상수를 사용하는 것이 좋습니다.

당신의 임시 뺑소니 프로그램 습관을 좋아한다고 해서 규칙을 만들거나 그것에 반대하는 어떤 말도 하지 마세요.

총을 다룰 줄 모르거나 총을 남용하기 쉬운 사람들이 있다는 이유로 총기 소유를 금지하지 마세요.

작성한 규칙이 전문적으로 코드화할 수 없는 초보자 프로그래밍을 위한 것이며, 그 안에 자신을 포함시킬 수 있는 것이라면 그렇게 말하십시오. fatwa를 적절하게 정규화된 데이터 모델에 적용할 수 있다고 선언하지 마십시오.

바보 같은 추론 - 인터페이스는 자바 언어의 창시자에 의해 그렇게 사용되도록 의도된 것이 아니다.

미국 헌법에 대한 건국의 아버지들의 초심이 무엇이었는지는 상관하지 않는다.불문율적인 의도 따윈 신경 안 써나는 성문헌법에 무엇이 성문화되어 있는지, 그리고 사회의 효과적인 기능을 위해 어떻게 그것들을 이용할 수 있는지에 대해서만 관심이 있다.

자바 언어/플랫폼 사양이 무엇을 가능하게 하는지에만 관심이 있습니다.소프트웨어 솔루션을 효율적이고 효과적으로 표현할 수 있는 매체를 제공하기 위해 최대한 활용하려고 합니다.재킷은 필요 없습니다.

Enum 상수 사용은 실제로 끔찍한 관행입니다.

매개 변수를 값에 매핑하려면 추가 코드를 작성해야 합니다.매핑 코드가 Enum 상수임을 나타내는 당신의 글 없이는 Java의 설립자가 파라미터와 값의 매핑을 제공하지 않았다는 사실도 의도하지 않은 Java 언어의 사용입니다.

특히 파라미터를 정규화하고 컴포넌트화하는 것이 권장되지 않기 때문에 Enum 백에 혼합된 파라미터가 같은 차원에 속한다는 잘못된 인상이 있을 수 있습니다.

상수는 API 계약입니다.

그걸 잊지 말게.데이터 모형을 설계 및 정규화하고 상수를 포함하는 경우 이러한 상수는 계약입니다.데이터 모델을 정규화하지 않은 경우, 이러한 나쁜 습관에 대처하기 위해 제한된 코딩 방법을 알려준 fat에 따라야 합니다.

따라서 인터페이스는 상수 계약을 구현하는 완벽한 방법입니다.

이상한 가정 - 인터페이스가 잘못 실장되면 어떻게 됩니까?

네, 누구나 부주의로 인터페이스를 구현할 수 있습니다.그런 부주의한 프로그래머를 방해하는 것은 아무것도 없다.

데이터 모델을 설계 및 표준화하여 유출 방지

API에 계약되지 않은/스트레이 파라미터가 유출되는 것으로 추정되는 불량관행을 보호하기 위한 제한규정을 두지 마십시오.인터페이스 상수에 책임을 돌리는 것이 아니라 근본적인 문제를 해결합니다.

IDE를 사용하지 않는 것은 잘못된 관행입니다.

정상적이고 효과적인 프로그래머는 그녀가 얼마나 오랫동안 물속에 있을 수 있는지, 그녀가 얼마나 멀리까지 갈 수 있는지, 또는 비에 젖은 뇌우 속에서도 증명하기 위해 그곳에 있지 않다.그녀는 매일 10마일을 차로 출근하기 위해 자동차나 버스 또는 최소한 자전거와 같은 효율적인 도구를 사용해야 한다.

IDE 없는 프로그래밍에 대한 난해한 금욕주의가 있다고 해서 동료 프로그래머에게 제한을 두지 마십시오.

몇 가지 프레임워크는 프로그래머가 계속해서 효율적으로 나쁜 습관을 연습할 수 있도록 설계되어 있습니다.

OSGI는 그런 프레임워크입니다.인터페이스 상수에 대한 법령도 마찬가지입니다.

따라서 최종적인 답변은...

인터페이스 상수는 적절하게 설계되고 정규화된 데이터 모델의 컴포넌트에 배치하는 효과적이고 효율적인 방법입니다.

클래스 파일에 네스트된 적절한 이름의 프라이빗인터페이스의 인터페이스 상수도 파일 전체에 분산하는 것이 아니라 모든 프라이빗 상수를 그룹화하는 것이 좋습니다.

나는 지금 이 오래된 질문을 여러 번 접했지만 받아들여진 답변은 여전히 나를 혼란스럽게 한다.심사숙고 끝에 이 문제는 더욱 명확해질 수 있을 것 같습니다.

인터페이스 상수를 사용하는 이유

비교만 하면 됩니다.

public final class Constants {

    private Constants() {
        // restrict instantiation
    }

    public static final double PI = 3.14159;
    public static final double PLANCK_CONSTANT = 6.62606896e-34;
}

public interface Constants {

    double PI = 3.14159;
    double PLANCK_CONSTANT = 6.62606896e-34;
}

같은 용도입니다.훨씬 적은 코드.

나쁜 관행?

@Pascal Thivent의 답변은 잘못된 강조를 가지고 있다고 생각합니다.제 버전은 다음과 같습니다.

스태틱 멤버를 인터페이스에 배치(및 그 인터페이스를 실장)하는 것은 나쁜 방법입니다.

Effective Java의 인용문에는 항상 다른 사용자가 구현하고 있는 인터페이스를 상정하고 있습니다.이러한 상황은 일어나지 않아야 한다고 생각합니다(그렇지 않으면 안 된다고 생각합니다.

음음음 named named named named named named named named named named named named named등의 이름의 고정 Constants(하지만, 유일한 문제

표준 라이브러리에서는 발생하지 않습니다.

스탠다드 라이브러리에서는 설계의 오용 가능성을 배제할 수 없기 때문에, 거기서 아무것도 볼 수 없습니다.

그러나 일반 개발자의 일상적인 프로젝트에서는 상수 인터페이스를 사용하는 것이 훨씬 쉽습니다.static,final,empty constructor등, 디자인상의 문제는 발생하지 않습니다.내가 생각하는 유일한 단점은 여전히 " 인터페이스"이라고 생각할 수 있지만, 그런 것보다 더 이상 없다.제가 생각할 수 있는 유일한 단점은 아직 '인터페이스'라는 이름을 가지고 있다는 것입니다만, 그 이상은 아닙니다.

끝없는 토론

마지막에는 모두가 책을 인용하고, 자신의 스탠드에 의견과 정당성을 제시하는 것이라고 생각합니다.예외는 없습니다.각 프로젝트의 개발자가 결정할지도 모릅니다.편하시면 그냥 쓰세요.우리가 할 수 있는 최선의 방법은 프로젝트 내내 일관되게 하는 것입니다.

Joshua Bloch, "효과적인 Java - 프로그래밍 언어 가이드":

인터페이스 패턴이 일정하면 인터페이스가 제대로 사용되지 않습니다.클래스가 내부적으로 일부 상수를 사용하는 것은 구현 세부 사항입니다.지속적인 인터페이스를 구현하면 이 구현 세부 정보가 클래스의 내보낸 API로 유출됩니다.클래스가 일정한 인터페이스를 구현하는 것은 클래스 사용자에게 중요하지 않습니다.사실, 그것은 그들을 혼란스럽게 할 수도 있다.더 나쁜 것은 이것이 약속임을 나타냅니다.앞으로 출시될 릴리스에서 클래스가 상수를 사용할 필요가 없도록 변경된 경우에도 바이너리 호환성을 확보하기 위해 인터페이스를 구현해야 합니다.비최종 클래스가 일정한 인터페이스를 실장하고 있는 경우, 그 서브 클래스의 모든 네임스페이스는 인터페이스의 상수에 의해 오염됩니다.

인터페이스를 구현하는 클래스에서 사용되는 공통 상수가 있는 경우 유용합니다.

다음은 예를 제시하겠습니다.http://www.javapractices.com/topic/TopicAction.do?Id=32

단, 인터페이스 상수가 아닌 스태틱 Import를 사용하는 것이 좋습니다.다음은 참고 자료입니다.http://www.javapractices.com/topic/TopicAction.do?Id=195

매우 공명할 수 있는 답변들이 있다.

하지만 나는 이 질문에 대해 몇 가지 생각이 있다.(잘못될 수 있음)

내 생각에 인터페이스의 필드는 프로젝트 전체의 상수가 되어서는 안 된다.인터페이스와 인터페이스의 확장 및 이들 인터페이스를 구현하거나 이와 밀접한 관계가 있는 클래스의 수단일 뿐이다.글로벌하지 않은 특정 범위 내에서 사용해야 합니다.

인터페이스에 관한 2가지 포인트:

  • 인터페이스는 그것을 구현한 객체가 할 수 있는 일의 서브셋을 기술한다(이것은 직관이다).

  • 인터페이스는 공통 상수와 그 상수를 구현하는 객체를 기술합니다.

    • 이러한 공통 상수는 클라이언트가 이러한 개체에 대해 더 잘 알 수 있도록 하기 위한 입니다.
    • 따라서 상수 인터페이스전역 상수를 정의하는 데 반직관적입니다. 인터페이스는 모든 개체아니라 일부 개체설명하는 데 사용되기 때문입니다(글로벌의 의미를 고려).

따라서 상수 인터페이스가 글로벌 상수에 사용되지 않으면 다음과 같이 허용됩니다.

  • 이러한 공통 상수의 이름이 좋은 경우 구현자에게 사용을 권장합니다(아래 예에 대한 첫 번째 요점을 참조하십시오).
  • 특정 분류에 따라 클래스를 동기화하려면 래 스 양 라 래 당 기 스 a if면동ification려, want the하 following spec클해 classes just class와화따사 those toimplements이 공통 상수는 구현에서 이러한 공통 상수를 사용합니다.(물론 구현에 이러한 공통 상수를 사용합니다)

예:

interface Drawable {

    double GOLDEN_RATIO = 1.618033988;
    double PI = 3.141592653;
    ...

    // methods
    ...
}

public class Circle implements Drawable {
    ...
    public double getCircumference() {
        return 2 * PI * r;
    }
}

void usage() {

    Circle circle = new Circle(radius: 3.0);
    double maxRadius = 5.0;

    if ( circle.getCircumference() < 2 * Circle.PI * maxRadius ) {
        ...
    }

}

이 예에서는 다음과 같습니다.

  • 터에서Circle implements Drawable, , you immediately know that 즉석에서 알 수 있습니다.Circle의 정 되 어 는 수 거 능 을 습 conform성 is있가다이니있 in준 probably defined고에있상하ed에 to the constants is conform .Drawable이므로 더 나쁜 해야 한다.PI ★★★★★★★★★★★★★★★★★」GOLDEN_RATIO★★★★★★★★★★★★★★★★★★★★★★★!
  • '만'DrawablePI ★★★★★★★★★★★★★★★★★」GOLDEN_RATIO되어 있습니다.Drawable 이 있을 수 .Drawable하다

이 질문을 하게 돼서 언급되지 않은 것을 추가하려고 합니다.일반적으로, 나는 여기서 파스칼의 대답에 동의한다.단, 인터페이스의 상수가 항상 '반대'라고는 생각하지 않습니다.

예를 들어 정의하는 상수가 그 인터페이스의 계약의 일부인 경우 인터페이스는 상수에 적합한 장소라고 생각합니다.경우에 따라서는 구현 사용자에게 계약을 공개하지 않고 파라미터를 개인적으로 검증하는 것이 적절하지 않을 수 있습니다.공개 계약 없이 사용자는 클래스를 디컴파일하고 코드를 읽지 않고 무엇을 검증했는지 추측만 할 수 있습니다.

따라서 인터페이스를 구현하여 계약 보증에 사용하는 상수(예를 들어 정수 범위)가 있는 경우 클래스 사용자는 인터페이스 자체의 상수와 대조하여 인터페이스 인스턴스를 올바르게 사용하고 있는지 확인할 수 있습니다.이는 상수가 구현에 대해 비공개이거나 구현이 패키지 개인이거나 다른 것이라면 불가능합니다.

인터페이스는 swing 클래스 간에 사용되는 스태틱필드를 취득한 예입니다.이 기능을 사용하면 다음과 같은 기능을 쉽게 사용할 수 있습니다.

  • this.add(LINE_START, swingcomponent);
  • this.add(this.LINE_START, swingcomponent);또는
  • this.add(SwingComponents.LINE_START, swingcomponent);

단, 이 인터페이스에는 메서드가 없습니다.

인터페이스 상수가 정적 최종 필드보다 우수한 컨텍스트가 하나 있습니다. 열거형입니다.인터페이스 상수는 열거된 상수 선언에서 사용할 수 있으며, 추가 지정 없이 열거에 부가된 이산값으로도 사용할 수 있습니다.예를 들어, 이 인터페이스는 다음과 같습니다.

public interface Name {
    String MANNY = "Manny";
    String MOE = "Moe";
    String JACK = "Jack";

    String getName();
}

...는 다음과 같은 열거형 상수에 사용할 수 있는 문자열 상수를 제공할 수 있습니다.

public enum PepBoys implements Name {
    BOY1(MANNY),
    BOY2(MOE),
    BOY3(JACK);

    private String name;

    PepBoys(String name) {
        this.name = name;
    }

    @Override
    public String getName() {
        return name;
    }
}

주석 특성의 값은 상수 값이어야 하며, 아이러니하게도 열거된 상수는 이 컨텍스트에서 '상수'로 적합하지 않습니다.단, 인터페이스에 정의되어 있는 문자열 상수는 다음 조건을 충족합니다.

@MyAnnotation(PepBoys.MANNY)
public void annotatedMethod() {
    ...
}

이러한 문자열 상수는 연관된 열거된 상수에 쉽게 다시 매핑할 수 있으며 각 상수는 한 번만 선언됩니다.유사한 결과를 얻을 수 있는 다른 방법이 있지만 이렇게 간결한 방법은 없으며 모두 최소한 두 개의 병렬 선언을 필요로 합니다.

클래스 간의 공유 상수를 다룰 때 인터페이스 상수를 사용합니다.

public interface TestConstants
{
    String RootLevelConstant1 = "RootLevelConstant1";

    interface SubGroup1
    {
        String SubGroupConstant1 = "SubGroup1Constant1";
        String SubGroupConstant2 = "SubGroup1Constant2";
    }

    interface SubGroup2
    {
        String SubGroupConstant1 = "SubGroup2Constant1";
        String SubGroupConstant2 = "SubGroup2Constant2";
    }
}

그룹화는 특히 많은 상수 집합을 가진 큰 자산입니다.

사용하기 위해서는, 그것들을 묶기만 하면 됩니다.

System.out.println(TestConstants.SubGroup1.SubGroupConstant1);
System.out.println(TestConstants.SubGroup2.SubGroupConstant1);
System.out.println(TestConstants.RootLevelConstant1);

공유하기 쉽고 추가 결합 없이 참조할 수 있도록 인터페이스에서 필드를 선언해야 합니다.

출처: Java Developer Tools 코딩 스타일

언급URL : https://stackoverflow.com/questions/2659593/what-is-the-use-of-interface-constants

반응형