중첩 된 공용 클래스를 사용하여 상수 구성


21

상수가 많은 응용 프로그램을 만들고 있습니다. 마지막 코드 검토에서 상수가 너무 흩어져 있고 모두 단일 "마스터"상수 파일로 구성되어야한다는 결과가 나왔습니다. 의견 불일치는 그들을 조직하는 방법에 관한 것입니다. 대다수는 상수 이름을 사용하는 것이 충분해야한다고 생각하지만 다음과 같은 코드가 생성됩니다.

public static final String CREDITCARD_ACTION_SUBMITDATA = "6767";
public static final String CREDITCARD_UIFIELDID_CARDHOLDER_NAME = "3959854";
public static final String CREDITCARD_UIFIELDID_EXPIRY_MONTH = "3524";
public static final String CREDITCARD_UIFIELDID_ACCOUNT_ID = "3524";
...
public static final String BANKPAYMENT_UIFIELDID_ACCOUNT_ID = "9987";

이 유형의 명명 규칙은 번거 롭습니다. 공개 중첩 클래스를 사용하는 것이 더 쉬울 것이라고 생각하고 다음과 같은 것이 있습니다.

public class IntegrationSystemConstants
{
    public class CreditCard
    {
        public static final String UI_EXPIRY_MONTH = "3524";
        public static final String UI_ACCOUNT_ID = "3524";
        ...
    }
    public class BankAccount
    {
        public static final String UI_ACCOUNT_ID = "9987";
        ...
    }
}

이 아이디어는 "너무 복잡해서"제대로 받아 들여지지 않았습니다 ( 이것이 왜 그렇게 복잡 할 수 있는지에 대해서는 자세히 알지 못했습니다 ). 이것이 관련 상수 그룹 사이에 더 나은 구분을 만들고 자동 완성을 통해 더 쉽게 찾을 수 있다고 생각합니다. 나는 이것을 한 번도 본 적이 없으므로 이것이 이것이 받아 들여지는 관행인지 아닌지 더 좋은 이유가 있는지 궁금합니다.


1
차라리 아이디어를 좋아합니다. C # 스타일 열거 형 범위 지정 및 동작을 원할 때 C ++에서 비슷한 것을하고 있지만 의미있는 가치가 있습니다 (스칼라에서 열거 형 대신 사례 클래스를 사용하는 데 익숙해 져서 아이디어가 생겼습니다). 물론 이것은 팀 작업이 아니라 재미를위한 개인적인 프로젝트였습니다.
KChaloux

답변:


13

두 제안 중 하나에 동의하지 않습니다.

상수는 자신에 있어야합니다 관련 클래스 , 아닌 모든 일정 클래스두 가지 형태 중 하나를 제안했다.

상수 전용 클래스 / 인터페이스가 없어야합니다.

클래스 CreditCard(안 내부 클래스)이 존재한다. 이 클래스 / 인터페이스는 신용 카드뿐만 아니라 상수를 기준으로 방법이 UI_EXPIRY_MONTHUI_ACCOUNT_ID.

BankAccount내부 클래스가 아닌 클래스 / 인터페이스가 있어야합니다 . 이 클래스 / 인터페이스에는 은행 계좌와 관련한 메소드와 상수가 UI_ACCOUNT_ID있습니다.

예를 들어 Java API에서 모든 클래스 / 인터페이스에는 상수가 있습니다. 내부 클래스로 그룹화되거나되지 않은 수백 개의 상수가있는 Constants 클래스 / 인터페이스에 없습니다.

예를 들어, 결과 집합과 관련된 이러한 상수는 인터페이스에 있습니다 ResultSet.

static int  CLOSE_CURSORS_AT_COMMIT 
static int  CONCUR_READ_ONLY 
static int  CONCUR_UPDATABLE 
static int  FETCH_FORWARD 
static int  FETCH_REVERSE 
static int  FETCH_UNKNOWN 
static int  HOLD_CURSORS_OVER_COMMIT 
static int  TYPE_FORWARD_ONLY 
static int  TYPE_SCROLL_INSENSITIVE 
static int  TYPE_SCROLL_SENSITIVE 

이 인터페이스에는 결과 집합과 관련된 메서드 서명이 있으며 구현 클래스는 해당 동작을 구현합니다. 그들은 단지 일정한 보유자가 아닙니다.

UI 작업과 관련된 이러한 상수는 인터페이스에 있습니다 javax.swing.Action.

static String   ACCELERATOR_KEY 
static String   ACTION_COMMAND_KEY 
static String   DEFAULT 
static String   LONG_DESCRIPTION 
static String   MNEMONIC_KEY 
static String   NAME 
static String   SHORT_DESCRIPTION 
static String   SMALL_ICON 

클래스를 구현하는 것은 UI 작업과 관련하여 동작이 있으며 단순한 홀더가 아닙니다.

나는 SwingConstants메소드가없는 적어도 하나의 "상수"인터페이스 ( )를 알고 있지만 수백 개의 상수가 없으며 몇 가지만 있으며 UI 요소의 방향과 위치와 관련이 있습니다.

static int  BOTTOM 
static int  CENTER 
static int  EAST 
static int  HORIZONTAL 
static int  LEADING 
static int  LEFT 
static int  NEXT 
static int  NORTH 
static int  NORTH_EAST 
static int  NORTH_WEST 
static int  PREVIOUS 
static int  RIGHT 
static int  SOUTH 
static int  SOUTH_EAST 
static int  SOUTH_WEST 
static int  TOP 
static int  TRAILING 
static int  VERTICAL 
static int  WEST 

상수 만 클래스가 좋은 OO 디자인이 아니라고 생각합니다.


1
상수 클래스 만 대부분 설계가 잘못되었다는 데 동의하지만 합법적 인 용도가 있습니다. 예를 들어, 상수가 항상 특정 클래스에 속하는 것은 아닙니다. 안드로이드 프로그래밍에서 인 텐트 엑스트라를위한 키가 그러한 구체적인 예 중 하나입니다.
curioustechizen

1
+1이지만 UI 상수는 BankAccount와 같은 비즈니스 모델에 있어서는 안됩니다. 그들은 일부 UI 클래스에 속합니다.
케빈 클라인

10

상수가 너무 흩어져서 모두 하나의 "마스터"상수 파일로 구성되어야합니다.

상수가 "찾기 어렵다"는 문제에 대한 100 % 잘못된 해결책 입니다. 상수, 열거 또는 인터페이스와 같은 기술 기준으로 사물을 그룹화하는 것은 (아쉽게도 프로그래머가 너무 일반적으로 범하는) 근본적인 오류입니다.

레이어 아키텍처를 제외하고는 사물을 도메인별로 그룹화해야하며 매우 낮은 수준의 요소이므로 상수가 더 많이 필요합니다. 상수는 API의 일부로 사용하는 클래스 또는 인터페이스의 일부 여야합니다. 그들이 살 수있는 자연스러운 장소를 찾을 수 없다면 API 디자인을 정리해야합니다.

또한 상수가 컴파일 타임에 사용되는 클래스에 인라인되어 있기 때문에 하나의 거대한 상수 파일이 Java에서 개발 속도를 저하 시킵니다. 어디서나 사용되는 상수를 가진 하나의 파일이 있으면 증분 컴파일의 이점을 크게 잃게됩니다. Eclipse가 파일을 변경할 때마다 전체 프로젝트를 다시 컴파일 할 때 15 분 동안 Eclipse가 잠기는 것을 지켜보십시오. 그리고 그 파일에는 모든 곳에서 사용되는 모든 상수가 포함되어 있기 때문에 자주 변경하게됩니다. 예, 나는 개인적인 경험에서 말하고 있습니다.


개발 환경에 미치는 잠재적 영향을 알지 못했으며 중첩 클래스 접근 방식이 그다지 도움이되지 않는 것 같습니다.
FrustratedWithFormsDesigner

1
@FrustratedWithFormsDesigner : 증분 컴파일 메커니즘이 모델링 종속성에 얼마나 많은 노력을 기울이고 있는지에 달려 있습니다.
Michael Borgwardt

9

네 말이 맞아 귀하의 제안을 통해 프로그래머 import static Constants.BankAccount.*는 'BANKACCOUNT_'의 수많은 반복을 제거 할 수 있습니다. 연결은 실제 범위 지정을 대체하기에 적합하지 않습니다. 즉, 팀 문화를 바꿀 수있는 많은 희망이 없습니다. 그들은 올바른 관행에 대한 개념을 가지고 있으며, 당신이 그들에게 그들이 틀렸다고 말하는 100 명의 전문가를 보여 주더라도 변하지 않을 것입니다.

또한 왜 하나의 '상수'파일이 있는지 궁금합니다. 이러한 상수가 모두 관련이 있고 매우 안정적인 경우가 아니라면 이는 매우 나쁜 습관입니다. 더 일반적으로 그것은 끊임없이 변화하고 모든 것에 의존하는 일종의 주방 싱크 수업이됩니다.


우리는 현재 대부분의 UI 필드 ID 상수를 포함하는 하나의 상수 파일과 하위 프로젝트 고유의 두 가지 다른 상수 파일을 가지고 있습니다. 그러나 이제는 하위 프로젝트 별 상수를 다른 관련 하위 프로젝트에서 사용해야하므로이를 하나의 "마스터"상수 파일로 병합해야합니다. 때로는 어떤 상수 파일이 값을 참조하는지 알지 못하기 때문에 다른 하위 프로젝트의 상수 파일에서 상수를 찾을 수 없기 때문에 누군가가 상수의 복제본을 만들었 기 때문에 지금보다 좋습니다.
FrustratedWithFormsDesigner

8
끊임없이 변화하는 상수 클래스 ... 충분히 파면 거기에 선이 있습니다.
KChaloux

2
@FrustratedWithFormsDesigner : UI 필드 ID? 어디에서 가치를 찾을 수 있는지 모르십니까? 거대한 WTF 더미처럼 들립니다. 당신은 내 동정심을 가지고 있습니다.
kevin cline

6

두 가지 접근 방식이 모두 효과가 있으며 이는 하루가 끝날 때 중요합니다.

즉, 귀하의 접근 방식은 패턴으로 간주되기에 충분하거나 일정한 인터페이스 안티 패턴 보다 더 정확하게 향상 됩니다. 복잡한 점은 보이지 않지만 팀과 논의해야 할 내용입니다.


충분히 긴 상수 목록을 보려면 동일한 클래스에 모두있는 것보다 상수 인터페이스를 선호합니다. 자동 완성에서 잘못된 것을 선택하는 것은 위험합니다. 물론, 그것은 얼마나 오래
걸리는가

1
@GoranJovic 모든 안티 패턴은 어떤 식 으로든 (또는 적어도 편리하게) 유용합니다. 그렇지 않은 경우 패턴이되지 않습니다.
yannis

1

긴 상수 목록의 문제점 중 하나는 사용할 "정확한"상수를 찾는 것입니다. 항상 누군가가 속한 그룹에 상수를 추가하는 대신 줄 끝에서 상수를 가져옵니다.

팀과 논의 할 또 다른 요점이 있습니다. 이미 이름을 통해 상수가 사실상 분류되어 있습니다. 따라서 현재 상태에서 제안하는 것으로 크게 전환해서는 안됩니다. 자동 완성 기능을 사용하면 지속적인 검색이 훨씬 쉬워집니다.

어떤 경우에는 제안이 특정 상황에 맞더라도 "잘못된"상수를 사용하지 않는 것이 좋습니다. 대표 클래스 내에서 상수를 줄임으로써 개발자가 사용해야하는지 생각하도록 장려 할 것입니다. 예를 들어, CreditCard.SomeConstant일반적인 사용을 원한다면 General.SomeConstant그 상황에 대한 이유가없는 이유가 정말로 궁금 합니다.

나는 엄청난 양의 상수를 가진 프로젝트를 진행해 왔으며 제안한 방법을 선호합니다. 더 깨끗하고 직접적이며 부주의 한 사용을 피하는 데 도움이됩니다.


1

나는 종종 (C #에서), 특히 잘 알려진 고정 XML 구조 또는 유사하게 중첩되고 문자열이 무거운 것 (예 : 사용자 정의 구성 블록 파서)에 대해 프로그래밍 / 구문 분석 해야하는 경우이 작업을 수행합니다.

const 문자열 "ElementName"속성을 포함하는 요소에 해당하는 클래스 이름과 각 속성에 해당하는 유사한 속성이있는 XML의 계층 구조와 일치하는 중첩 클래스 구조를 작성합니다 (있는 경우).

해당 Xml에 대해 프로그래밍하기가 매우 쉽습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.