'annotation'에 해당되는 글 2건

  1. 2006.12.16 DDD를 위한 새로운 annotation의 제안 (7)
  2. 2006.12.05 Hibernate Annotation 3.2 버그?

DDD를 위한 새로운 annotation의 제안

엔터프라이즈 자바 2006. 12. 16. 12:17 posted by 엔트웍스
JCP 애들은 도대체 왜 이런 애너테이션annotation을 만들 생각을 안할까요?

public class Customer {
   @Getter @Setter
   private String name;
   ....
}

(이게 C#에는 보았는지 들었는지 아무튼 있다 하던데, 귀차니즘 때문에 굳이 찾아보지는 않겠습니다만 아시는 분은 댓글 달아주시면 감사하겠습니다.)

이렇게 해 주면 컴파일러가 자동으로 getter 메소드와 setter 메소드를 컴파일된 클래스 안에 넣어줍니다. 마치 아무 생성자도 정의하지 않으면 기본 생성자default constructor를 컴파일러가 알아서 넣어 주는 것처럼 말이죠. 그럼 이 클래스를 쓸 때는 예전대로 쓰면 될겁니다.

customer.setName(aName); // (1)

대부분의 IDE가 getter/setter 소스를 자동 생성[fn]getter/setter 용 필드를 굳이private로 해서 고생하지 말고 아예 public으로 하자는 분들도 있습니다. 그런데 현실적으로 getter/setter는피할 수 없어 보입니다. JSP의 EL이나 여러 오픈소스 프레임워크/라이브러가 JavaBeans 규칙에 의존하고 있거든요.조조가 별로 가치도 없는 한중을 어쩔 수 없이 쳐야 했듰이, getter/setter는 객체지향 언어의 계륵같은 존재인가 봅니다.[/fn] 해 주니까 별 필요가 없다고 생각하는 걸까요? 사실 (1) 처럼만 쓴다면 소스 생성이나 애너테이션이나 별 차이가 없어 보입니다.

그런데 저는 강력히 그 필요성을 느낍니다. 왜? 아래와 같이 쓰고 싶기 때문입니다.

customer.name = aName; // (2)

소스 생성 기반이라면 이 코드는 컴파일도 되지 않을 겁니다. 액세스 권한access previlege 어쩌구 하면서 말이죠. 그런데 애너테이션 기반이라면 컴파일러가 단순히 getter/setter를 컴파일된 클래스 안에 넣어줄 뿐만 아니라, 사용하는 코드를 컴파일할 때도 인식이 가능해 집니다. 즉 (2)의 코드를 (1)로 보고 컴파일 하면 되는 것입니다. = 연산자와 setter를 매칭시키는 것이죠. getter는 훨씬 간단할 것이구요. 물론 name 멤버에 애너테이션을 적용하지 않았다면 컴파일 시 에러를 뱉어야 겠죠.

그럼 (2)와 같이 해서 뭐가 좋으냐고요? 예, 제 진짜 의도는 아래와 같이 코드를 한글로 작성하고 싶기 때문입니다.

고객.이름 = 이름;
고객.주민번호 = 주민번호;

만약 위의 코드처럼 작성할 수 있다면 훨신 높은 가독성의 코드가 만들어질 것입니다. 또한 코드상으로는 멤버변수에 직접 액세스하는 것으로 보이지만 실제로는 메소드를 통해서 접근이 이루어 지므로, 객체지향  원칙을 깨트리지도 않습니다.

그런데 왜 굳이 getter/setter 대신 도트 표기dot notation을 사용해야 하는지는, 다음과 같이 getter/setter를 사용하는 한글 코드와 대조해 보면 차이를 분명히 알 수 있습니다.

고객.set이름(이름);
고객.set주빈번호(주민번호);

제 눈에는 무지하게 흉칙하게 보입니다. 매 라인마다 한영전환해야 하는 수고도 피할 수 없습니다. 차라리 원래 영어로만 쓰던 코드가 낫겠습니다.

DDD(Domain Driven Design)에서 도메인 모델은 유비퀴터스 랭귀지ubiquitous language라 했습니다. 그런데 이 유비퀴터스 랭귀지를 되도 않는 영어로 표현해야 하는 걸까요? 영어로 표현하다 보니 어느 애플리케이션을 뒤져봐도 꼭 나오는 gubunCd 라던가 juminNo 같은 변수명 코미디가 생기는 겁니다. 계약이 agreement냐 contract냐 이런거 가지고 싸울 일도 없으며, agreement를 코드에서 보고는 '동의'가 여기서 왜 나오지? 하고 고민하는 프로그래머도 생기지 않을 겁니다. 따라서 한글로 모델을 만들고 코드화 하는 것은 한국의 DDD에 있어 필수불가결하지 않을까 생각합니다.

그리고 자바에서 이러한 한글 표현을 위해서는 무엇인가 표준적인 표기법이 필요한데, JavaBeans 규칙을 위반하지 않으면서도 한글 표기를 현실적으로 가능하게 하기 위해서는 도트 표기법과 애너테이션을 조합하는 방법밖에 없어 보입니다.

문제는 이러한 기능은 컴파일러 수준에서 인식해야 하는 것이라, @Override 처럼 자바 기본 패키지에 포함되어 스펙화 되지 않으면 안됩니다. 그런데 호랭이tiger(Java 5)는 이미 옛날 이야기가 되었고 벌써 야생마mustang(Java 6)까지 공식적으로 등장하셨으므로 야생마에 적용하는 것도 물건너 갔습니다. 이젠 돌고래dolphin(Java7)에 이런 기능이 추가되기를 바랄 수 밖에 없네요.

저는 이 애너테이션을 강력히 원합니다. 특히 한국인이 작성하는 코드에 필요성을 절실히 느낍니다. 제발 돌고래에라도 넣어주세요!
  1. Commented by Favicon of http://cbiscuit.info BlogIcon cbiscuit at 2006.12.16 13:42

    C#으로 짜자!

  2. Commented by Favicon of http://crosscutter.info BlogIcon 지훈 at 2006.12.20 12:28

    주말에 사무실에 나와 시간이 생겨서 직접 찾아보았습니다. C#에는 아예 get/set 키워드가 존재하는군요. 이것도 좋아 보이네요. 자세한 내용은,
    http://www.csharphelp.com/archives/archive27.html
    을 참고하세요.

  3. Commented by Favicon of http://toby.epril.com BlogIcon 토비 at 2006.12.22 09:18

    자존심 때문에 C# 따라한다는 얘기를 듣기 싫어서 그럴 겁니다.

    • Commented by Favicon of http://crosscutter.info BlogIcon 지훈 at 2006.12.22 12:23

      C#을 따라한다고 부끄러워할 게 아니라, 좋은 점을 빨리 수용 안하는 것을 부끄러워해야 할 텐데 말이죠.
      그런데 이걸 좋은 점이라고 생각하는 것은 저 뿐일까요? -_-

  4. Commented by Favicon of http://www.ologist.co.kr BlogIcon ologist at 2006.12.31 11:56

    저는 TestCase를 한글을 이용해 사용을 하는데, 메소드 이름까지는 가독성이 좋아보이지만, 클래스명과 변수명까지 한글로 적으니, 코드가 한눈에 들어오지 않더군요. 일단 public으로 해서 코드를 작성해서 전체적으로 코드를 한번 보는 것도 좋은 방법인듯 합니다. 마음에 들면 @properties라는 annotation을 작성해서 사용을 하는 것도 좋을거 같네요. 잘 기억이 안나지만, EJB3.0에는 있던거 같은데...

    ex) InputTest.java
    public void test_입력값이올바른가(){
    int a = 1;
    assertTrue( 1 , a);
    }

    • Commented by Favicon of http://crosscutter.info BlogIcon 지훈 at 2007.01.02 10:10

      저도 한글 테스트케이스 코드 좋아합니다. 한글을 좋아하는 분이 계시니 기쁘군요.

  5. Commented by Favicon of http://www.timberlandbaratas.com BlogIcon Timberland shops at 2012.12.25 12:35

    La chanteuse américaine Shania Twain s'est mariée, http://www.timberlandbaratas.com Timberland shops, à Puerto Rico, http://www.timberlandbaratas.com timberland niños, samedi, http://www.timberlandbaratas.com barato timberland, rapporte le site spécialisé dans les célébrités TMZ, http://www.timberlandbaratas.com Timberland Online.com, http://www.timberlandbaratas.com outlet timberland, le jour-même, http://www.timberlandbaratas.com zapatos timberland. People David Arquette en désintoxication People Nouvel album de Lady Gaga : 23 maiRelated articles:


    http://zankke.tistory.com/52 Des milliers de Pakistanais ont bravé mercredi à Lahore les menaces de violences pour assister aux
    %0

현재 hibernate 3.2와 hibernate-annotations 3.2.0.GA 버전을 사용중이다.
ProgramCategory라는 열거형enum을 정의하고 이를 VARCHAR 컬럼으로 매핑해야 하므로,
커스텀타입custom type으로 매핑하였다.
그런데 HQL에서는 작동하지 않는다(그 이외의 경우에는 작동).

아래는 커스텀타입custom type의 정의이다.
@TypeDefs(
   {
   @TypeDef(
       name="ProgramCategory_CUSTOM",
       typeClass = abc.framework.hibernate.StringValuedEnumType.class,
       parameters = {
           @Parameter(
               name="enumClassName",
                value="abc.programmgt.model.ProgramCategory"
           )

       }
   )
   }
)

아래는 위에서 정의한 커스텀타입을 실제 매핑하는 코드이다.
@Type(type="ProgramCategory_CUSTOM")
@Column(name="CATEGORY")
public ProgramCategory getCategory() { return category; }

아래는 HQL의 where 절 일부.
...
and p.category = :category
...


다음은 HQL을 실행하는 코드.
ProgramCategory category = ...;
query.setParameter("category", category);

어노테이션으로 정의한 경우에는 위에서 정의한 커스텀타입이 작동하지를 않고,
디버거를 돌려 보니 타입 결정 시에 java.io.Serializable로 결정해 버린다!
:category 요부분이 ProgramCategory가 직렬화된 문자열로 바뀐다 -_-;

꽤나 문제 찾는 데에 시간이 걸린 관계로 일단 아래와 같이 강제로 String으로 변환(DB 타입은 VARCHAR임)해보니 해결은 되었으나,
query.setString(
   "category", category == null? null : category.getValue());
영 찜찜한 것은 어쩔 수가 없다.

버그리포트로 올려야 하나...