IT

인터페이스 상수의 사용은 무엇입니까?

lottoking 2020. 7. 29. 07:36
반응형

인터페이스 상수의 사용은 무엇입니까?


Java를 배우고 인터페이스에 공개 정적 및 최종 필드가 있음을 발견했습니다. 나는 지금까지 설치된 예를 구비하고 있습니다. 이 인터페이스 상수의 사용 사례는 무엇이며 Java 표준 라이브러리에서 볼 수 있습니까?


정적 멤버를 인터페이스에 배치하고 해당 인터페이스를 구현하는 것은 나쁜 습관 이며 Constant Interface Antipattern 이라는 이름도 있습니다. 효과적인 Java , 항목 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);
    }
}

" 가는 인터페이스 패턴은 인터페이스를 잘 사용하지 않습니다 "

이 가설을 만든 사람은 누구나 나쁜 습관과 관행을 계속해서 이행해야 할 일을 근거하여 계속 이행해야합니다. 가설은 나쁜 디자인 습관의 타당성 소프트웨어에 기초합니다.

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

10 년 동안이 가설을 제안 화하는 이유를 게시 한 후 2 시간 내에 문을 닫을 때까지 그 질문은 계속 열려 있습니다.

이것이 내가 가설에 대해 표현한 요점입니다.

  • 이 가설을 세우기위한 것은 나쁜 소프트웨어 습관과 방법론의 영향에 대처하기위한 방법과 제한 규칙이 필요 기초 것입니다.

  • " 지속적인 인터페이스 패턴은 인터페이스를 잘 사용 하지 않는다 "감정의 지지자들은 나쁜 습관과 관행의 영향에 영향을 줄 필요가없는 다른 이유를 제공 할 수 없습니다.

  • 근본적인 문제를 해결하십시오.

  • 그런 다음 Java 언어 구조의 모든 언어 기능을 원하는대로 최대한 활용하고 활용하십시오. 규격이 필요하지 않습니다. 왜 더 효과적인 라이프 스타일을 차별하고 비난하기 위해 비효율적 인 라이프 스타일을 방해하는 규칙을 발명해야합니까?

근본적인 문제

정보 조직입니다. 프로세스를 중재하는 정보와 프로세스의 솔루션을 엔지니어링 보완하기 전에 소위 비즈니스 규칙과 함께 프로세스의 정보 및 동작을 먼저 이해해야합니다. 정식 정보 구성 방법은 전에 데이터 표준화라고 불렀습니다.

솔루션 구성 요소의 입도 및 모듈성을 구성 요소의 입도 및 모듈 성과 일치시키는 것이 최적의 전략이기 때문에 솔루션의 엔지니어링만이 가능합니다.

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

  1. 데이터 모델 "정규화"의 중개인에 대한 인식 부족.

  2. 데이터 정규화에 대한 EF Codd의 결함은, 결함 및 모호합니다.

  3. 민첩한 엔지니어링으로 가장 최근 유행 한 유행은 모듈 구성을 계획하고 조정 안 잘못된 생각입니다. 미래 발견에 방해받지 않고 리팩토링과 지속적인 변화가 변명으로 사용됩니다. 프로세스 정보의 행동에 대한 내부 인 발견은 회계 트릭을 사용하여 이익과 자산을 지연 필수 지식과 그 처리가 현재 필요하지 않은 것입니다.

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

특별한 촉촉한 프로그래밍 습관을 좋아하는 이유만으로 규칙을 만들거나 그에 대한 fatwa를 발행하지 않고.

총 취급 방법을 모르거나 총을 남용하기 쉬운 사람들이 있기 때문에 총 소유를 금지하지 않습니다.

당신이 만들어 낸 규칙이 프로그래밍을 할 수없고 당신이 전문적으로 코딩 할 수없고 당신이 그들 사이에 자신을 포함하면 그렇게 말-팻와를 정당화 할 수있는 데이터 모델에 적용 할 수 있습니다.

어리석은 추론-인터페이스는 Java 언어의 치가 그런 식으로 사용하지 않을 경우 갑자기 발생합니까?

나는 건국 조상들의 원래 의도가 미국 헌법에 대해 무엇을했는지 상관하지 않습니다. 나는 기록되지 않습니다. 의도하지 않습니다. 나는 헌법에 문학적으로 체계화되어있는 것과 사회의 효과적인 기능을 위해 존재하는 것과 동일한 기능에 있습니다.

Java 언어 / 플랫폼 사양에서 허용되는 것에 관심이 있고 소프트웨어 솔루션을 사용하기 위해 표현할 수있는 매체를 제공합니다. 규격이 필요하지 않습니다.

열거 형 상수 사용은 실제로 끔찍한 연습입니다.

숫자 변수를 값에 매핑하려는 경우 추가 코드를 작성해야합니다. Java의 설립자가 매핑 코드가 Enum Constants가 의도하지 않은 Java 언어 사용을 보여 준다는 것을 작성하지 않고 매개 변수 값 매핑을 제공하지 않습니다.

특히 매개 변수를 정규화하고 구성 요소로 분류하지 않기 때문에 Enum 백에 혼합 된 매개 변수가 동일한 차원에 속한다는 인상이있을 수 있습니다.

상수는 API 계약입니다

잊지 마세요. 데이터 모델을 설계하고 정규화하고 상수를 포함하는 경우 해당 상수는 계약입니다. 데이터 모델을 정규화하지 않은 경우 나쁜 습관에 행동하기 위해 제한적인 코딩을 연습하는 방법에 대한 지방을 준수해야합니다.

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

이상한 추정-인터페이스가 우연히 구현되면 어떨까요?

예. 누구나 실수로 인터페이스를 실수로 구현할 수 있습니다. 그러한 부주의 한 프로그래머를 방해하는 것은 없습니다.

누출에 대한 데이터 모델 설계 및 정규화

계약되지 않은 / 잘못된 매개 변수가 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;
}

vs

public interface Constants {

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

같은 사용법. 훨씬 적은 코드.

나쁜 습관?

@Pascal Thivent의 답변에 잘못된 강조가 있다고 생각합니다. 여기에 내 버전이 있습니다.

정적 멤버를 인터페이스에 넣고 해당 인터페이스 를 구현하는 것은 나쁜 습관입니다.

Effective Java의 인용문에는 다른 사람들이 지속적인 인터페이스를 구현하고 있다는 가정이 있습니다.

와 같은 이름의 상수 인터페이스를 만들 때 Constants누구도 구현해서는 안됩니다. (기술적으로 가능하지만 여기서 유일한 문제입니다)

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

표준 라이브러리는 디자인의 오용 가능성을 감당할 수 없으므로 거기에서 아무것도 볼 수 없습니다.

그러나 당신이에 대해 걱정할 필요가 없기 때문에, 상수 인터페이스를 사용하여 일반 개발자의 일상 프로젝트에 대한 많은 쉽게 static, final, empty constructor, 등, 그리고 어떤 나쁜 디자인의 문제가 발생하지 않습니다. 내가 생각할 수있는 유일한 단점은 여전히 ​​"인터페이스"라는 이름이 있지만 그 이상은 없다는 것입니다.

끝없는 논쟁

결국 나는 모든 사람들이 책을 인용하고 그들의 입장에 대한 의견과 정당성을 부여한다고 생각합니다. 나를위한 예외는 없습니다. 결정은 여전히 ​​각 프로젝트의 개발자에게 달려 있습니다. 편안하다면 계속 사용하십시오. 우리가 할 수있는 최선 은 프로젝트 전체에서 일관성을 유지하는 것 입니다.


Joshua Bloch, "Effective Java-Programming Language Guide":

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


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

예 : http://www.javapractices.com/topic/TopicAction.do?Id=32

그러나 권장되는 방법은 인터페이스에서 상수 대신 정적 가져 오기를 사용하는 것입니다. 다음은 참조입니다. http://www.javapractices.com/topic/TopicAction.do?Id=195


매우 공감하는 답변이 있습니다.

하지만이 질문에 대해 몇 가지 생각이 있습니다. (틀릴 수 있음)

제 생각에, 인터페이스의 필드는 전체 프로젝트에 대한 상수가 아니어야합니다. 그것들은 인터페이스를위한 수단 일 뿐이며 인터페이스는이를 확장하고 이러한 인터페이스를 구현하거나 그들과 밀접한 관계를 갖는 클래스입니다. 글로벌이 아닌 특정 범위 내에서 사용해야합니다.


인터페이스에 대한 두 가지 사항 :

  • 인터페이스는 를 구현 하는 객체 가 수행 할 수있는 작업 의 하위 집합설명 합니다 . (이것이 직감입니다)

  • 인터페이스는이 를 구현하는 객체따르는 공통 상수를 설명 합니다.

    • 이러한 공통 상수 클라이언트가 이러한 객체에 대해 더 많이 알 수 있도록 알려줍니다.
    • 그래서 상수 인터페이스는 참으로 정의하는 직관적 인 글로벌 상수 인터페이스를 설명하는 데 사용되기 때문에, 일부 개체 가 아닌 모든 개체를 / 어떤 객체 (의 의미를 고려하지 글로벌을 ).

따라서 Constants Interface전역 상수에 사용되지 않으면 허용됩니다.

  • 이러한 공통 상수 에 좋은 이름 이 있으면 구현 자에게 사용하도록 권장 합니다 (아래 예제에 대한 첫 번째 요점 참조).
  • 클래스가 사양을 따르는 클래스와 동기화하려는 경우 해당 클래스 만 동기화 implements합니다 (물론 구현에서 이러한 공통 상수를 사용합니다).

예:

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, 당신은 바로 그 아는 Circle아마에 정의 된 상수에 따른다 Drawable그렇지 않으면 좋은 것들 때문에 더 나쁜 이름을 선택해야 PI하고 GOLDEN_RATIO이미 촬영되었습니다!
  • 만 이러한 Drawable오브젝트는 특정을 준수 PI하고 GOLDEN_RATIO정의 Drawable없는,있을 수있는 개체 Drawable파이와 황금 비율의 다른 정밀.

javax.swing.SwingConstants인터페이스 스윙 클래스 중 사용되는 정적 필드를 가지고 예이다. 이렇게하면 다음과 같은 것을 쉽게 사용할 수 있습니다.

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

그러나이 인터페이스에는 메소드가 없습니다 ...


나는이 질문을 보았고 언급되지 않은 것을 추가 할 것이라고 생각했습니다. 일반적으로, 나는 파스칼의 대답에 동의 여기 . 그러나 저는 인터페이스의 상수가 "항상"반 패턴이라고 생각하지 않습니다.

예를 들어, 정의하는 상수가 해당 인터페이스에 대한 계약의 일부인 경우 인터페이스가 상수를위한 좋은 장소라고 생각합니다. 어떤 경우에는 구현 사용자에게 계약을 노출하지 않고 매개 변수를 비공개로 검증하는 것이 적절하지 않습니다. 공개 계약이 없으면 사용자는 클래스를 디 컴파일하고 코드를 읽는 것없이 유효성 검사를 추측 할 수 있습니다.

따라서 인터페이스를 구현하고 인터페이스에 계약을 확인하는 데 사용하는 상수 (예 : 정수 범위)가있는 경우 클래스의 사용자는 인터페이스의 상수를 확인하여 인터페이스 인스턴스를 올바르게 사용하고 있는지 확인할 수 있습니다. 그들 자신. 상수가 구현에 전용이거나 구현이 패키지 전용이거나 다른 경우 불가능합니다.


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

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 개발자 도구 코딩 스타일

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

반응형