Enum 코딩 중 nested function 사용?

2013-03-18 19:20

안녕하세요.

enum에 여러 값이 들어가게 되면 그 값이 무엇인지 보려면 생성자를 확인해봐야 하잖아요, 그게 때때로는 불편하더라고요. 그래서 오늘 코딩하다가 한번 nested function을 사용해보았어요.

코드에 약간 겉멋이 든 느낌이 들기도 하지만 그래도 가끔 써보면 가독성 괜찮아보이긴 하는데 조금 고민이네요. 이렇게 코딩하는 것 싫어하는 분들도 많으시더라고요.

다른 분들은 대게 어떠세요? 그리고 아래 TYPE1, TYPE2 네이밍은 어떤가요?

	TYPE1(width(292), height(242), "넓이 640px 이하 용"),
	TYPE2(width(584), height(480), "넓이 1280px 이하 용");


	private int width;
	private int height;


	private BannerThumbnailType(int width, int height, String ignored) {
		this.width = width;
		this.height = height;
	}


	public int width() {
		return width;
	}


	public int height() {
		return height;
	}


	private static int width(int width) {
		return width;
	}


	private static int height(int height) {
		return height;
	}
}
BEST 의견 원본위치로↓
2013-03-19 10:30

width(), height() static 함수는 필요없지 않나요?

public enum BannerThumbnailType {
  TYPE1(292, 242, "넓이 640px 이하 용"}),
  TYPE2(584, 480, "넓이 1280px 이하 용");
 
  private int width;
  private int height;
 
  private BannerThumbnailType(int width, int height, String ignored) {
    this.width = width;
    this.height = height;
  }
 
  public int width() {
    return width;
  }
 
  public int height() {
    return height;
  }
}

이렇게 써도 될 거 같은데요. "넓이 640px 이하 용" 같은 문구는 주석으로 처리하는 게 어떨까 싶고요.

그리고, TYPE1, TYPE2 보다는 WIDTH_UNDER_640, WIDTH_UNDER_1280 이 어떨까요?

19개의 의견 from SLiPP

2013-03-19 09:44

지금까지 알지 못했던 완전히 새로운 구현 방식인데...

나는 지금까지 위와 같이 구현해 본 적이 없다. 새로운 구현 방식을 보여주어 고맙다. 사람에 따라 다르겠지만 가독성 측면을 고려한다면 위와 같은 구현 방식은 충분히 시도해볼만하다고 생각한다. 하지만 성능이라든가, 코딩량의 증가를 싫어하는 개발자라면 위와 같은 접근 방식은 네가 말한대로 겉멋이 들었다고 생각할 수도 있겠다.

TYPE1과 TYPE2는 이름이 다소 불명확하지 않나? 뒤에 Description으로 설명하는 부분을 Enum 이름으로 사용하려고 시도해 보거나 각 Type의 용도가 있다면 용도를 표기하는 것도 좋겠다는 생각이다. 예를 들어 TYPE1인 가장 작은 Thumbnail을 의미한다면 THUMBNAIL_SMALL, TYPE2는 THUMNAIL_MIDDLE과 같은 형태가 그나마 좀 더 낫지 않을까? 물론 이도 명확하지 않기는 않네.

2013-03-19 10:09

objective-c 스타일인뎅~ ^^ 개인적으로는 java스럽지 않아서 싫어용~ (개인적으로 ㅋ) 물론, objective-c로 코딩한다면 좋구용~

그리고, enum 인스턴스 이름도 별로 ^^; 오히려 설명에 있는 내용을 과감히 드러내는 것이 좋지 않을 까요? 위와 같이 별도로 enum class로 생성했다면 사용할 때 coding할 때 " BannerThumbnailType.TYPE1 " 위와 같이 하게 되지 않나요? 그럼 좀 어색해 보이는데? 괜찮아 보이시는지요? 오히려 " BannerThumbnailType.640 " 과감하게 해도 될 듯 해요.

또한, 이런 type이 위와 같이 애매한 경우가 있는데 이럴경우 막강한 java doc을 기술해 보세요. 해당 enum을 쓰는 다른 사람은 당신을 매우 사랑을 할 것입니다.

또한, nested function으로 코딩하는 것은 가독에 좋습니다. 다만, 가독을 위해 불필요한 method가 추가되는 느낌이 가볍게 받아 들이기는 쉽지 않습니다. 위와 같은 경우로 국한하여 더 언급해보면, 우리에 통념적으로 가로-세로라는 일반적인 관습의 쓰임새에서는 굳이 width height로 친절할 필요는 없을 것 같습니다. 다만, 세로-가로라고 써야하는 상황 더 나아가 더 복잡한 enum (enum이 복잡하면 ㅡ.ㅡa)인 경우는 고려 대상으로 생각할 수 있을 것 같습니다.

의견 올려 봅니다.~~

2013-03-19 10:30

width(), height() static 함수는 필요없지 않나요?

public enum BannerThumbnailType {
  TYPE1(292, 242, "넓이 640px 이하 용"}),
  TYPE2(584, 480, "넓이 1280px 이하 용");
 
  private int width;
  private int height;
 
  private BannerThumbnailType(int width, int height, String ignored) {
    this.width = width;
    this.height = height;
  }
 
  public int width() {
    return width;
  }
 
  public int height() {
    return height;
  }
}

이렇게 써도 될 거 같은데요. "넓이 640px 이하 용" 같은 문구는 주석으로 처리하는 게 어떨까 싶고요.

그리고, TYPE1, TYPE2 보다는 WIDTH_UNDER_640, WIDTH_UNDER_1280 이 어떨까요?

2013-03-19 11:47

@kangdonghyeok님 아마도 TYPE1 뒤에 따라오는 파라미터가 어떤 정보인지 한번에 인지하기 위함인 것 같아요. Named Parameter와 유사한 느낌을 줄 수도 있겠네요.


먼가 빌더의 느낌이 끙끙~

이름을 나타내기 위해서 함수를 하나 쓰는 것도 최적화는 잘되려나요? TYPE1, TYPE2 는 명시적이지 않아서 완전 싫고 자바 스타일이라면 명시 java doc을 쓰는 것이 좋을 것 같아요

2013-03-19 11:49

enum에서 Type명은 분명한 목적이나 상태를 표현해주어야 하기 때문에 TYPE1, TYPE2 보다는 이름이 길더라도 강동혁님께서 말씀하신대로 변경하는 것이 좋다고 생각합니다. 그리고 nested function은 내부 property명을 명확하게 정하면 불필요하다고 생각합니다.

덧붙여 내부 property를 final로 선언하여 확실한 제한을 걸어주는 것도 필요하다고 생각합니다.

2013-03-19 13:32

저도 이름은 kangdonghyeok님 생각과 같고요 설명부는 단순한 부연설명정도가 아니라 규약?규칙?과 같은 느낌이기때문에 유지보수를 위해(타입추가)서는 위와같이 설명부를 코드에 강제화하는게 좋아보이네요. :)

2013-03-19 15:58

Java의 생성자에 named parameter가 없어서 생기는 비극이네요. 그런데 어짜피 이 Enum의 생성자를 외부에서는 호출할 수 없고, 이 Enum코드를 들어다볼 사람을 위한 코드라면 아래와 같이 주석으로 해결하는 편이 더 자연스럽다고 느껴집니다. (코드 하일라이팅이 좀 이상하게 되었는데, WIDE_TYPE도 eclipse에서는 잘 인식됩니다)



public enum BannerThumbnailType { SMALL_TYPE(/*width*/292, /*height*/242), //넓이 640px 이하 용 WIDE_TYPE(/*width*/584, /*height*/480); // 넓이 1280px 이하 용 private int width; private int height; private BannerThumbnailType(int width, int height) { this.width = width; this.height = height; } public int width() { return width; } public int height() { return height; } }
2013-03-19 16:51

더블 브레이스 쓰는 방법도 있어요..



public enum ThumbnailType { SMALL_TYPE(){{width=292;height=242;}}, //넓이 640px 이하 용 WIDE_TYPE(){{width=584;height=480;}}; //넓이 1280px 이하 용 int width; int height; public int width() { return width; } public int height() { return height; } }
2013-03-19 17:30

@benelog 더블 블레이스 쓰는 방법도 있군요! 전에 시도 한번 했었던 같은 이상한 느낌도 드는데요...

tail comment는 인지가 어렵기 때문에 사용하지 않는 편이 좋겠다는 의견도 있지요...

저는 // 문구 자체를 임시코드에만 넣기 때문에 설명을 위해서라면 /* */ 를 선호합니다.

2013-03-19 17:34

@benelog http://www.ologist.co.kr/1003 이전에 이 주제로 페북에 올라와서 페북 댓글로 논했던 적이 있었습니다. 기억은 안 나는데 제가 그때 언급했던 부분 중 위 링크 내용외에.. tail comment는 소프 포맷터등을 이용하는 경우 new XXX(); //긴~~~~인 주석 을 포맷팅 하는 경우 new XXX(); //긴~~ //~~~ //인 주석 이런 모양새가 되는 경우도 있다고 언급했습니다.

물론, 주된 이유는 java doc과 comment 그리고, 리팩토링 등등 이야기가 길어질 것 같네요~~

의견 주셔서 감사합니다~~^^

2013-03-19 17:57

@hyukhur 아, 코드 끝 주석의 그런 측면을 말씀하시는거였군요. //와 /* */를 일관성 있게 쓰기 어려운데, 프로젝트에 따라서 //는 commenting out에만 쓴다는 규칙을 만드는 것도 괜찮은듯합니다.

2013-03-19 19:45

답변 많이 달아주셔서 감사합니다. 짧은 코드임에도 여러 관점에서 생각해보고 배울 수 있는 좋은 계기가 된 것 같아요.

추가로 TYPE1, TYPE2에 대안으로 주신 의견에 대해 고민했던 내용을 적어봅니다.

  1. WIDTH_UNDER_640, WIDTH_UNDER_1080 이 네이밍을 심각하게 고민했었습니다. 그런데, 해당 썸네일은 넓이 640 이하에서 혹은 1080이하에서 사용한다는 현재의 규칙(언제든 바뀌어도 이상치 않은)이고, 어떤 관점에서는 Use Case에 가깝다는 생각이 들었습니다. 그렇다면 Use Case에 대한 정보를 Enum을 가지고 있어야 하나? Use Case는 바뀔 수 있는거 아닌가? (즉, A 유형의 썸네일을 어떤 용도로 어떻게 쓸지는 충분히 바뀔 수 있다) 이런 질문을 스스로 하다가 안 쓰기로 했습니다.

  2. SMALL, MEDIUM, LARGE 이 네이밍도 고민했었습니다. 모두 마찬가지이겠지만 지금 일하고 있는 조직은 기획이 시시각각으로 바뀌고, 실제 개발 도중에서 썸네일에 대한 스펙이 논의되곤 했습니다. 즉, 변경과 확장을 감안했는데요. 이런 관점에서 볼 때 만약 나중에 SMALL보다 더 작은 width/height을 가진 썸네일 유형이 추가되면 이름을 무엇으로 지어야 하지?라는 의문이 들었습니다. VERY_SMALL? 또 나오면? 이런 생각을 하다 보니 이것 역시 사용하기 어려웠습니다.

그래서 결국 저는 위와 같이 TYPE1, TYPE2를 사용하게 되었습니다만 지금도 고민이긴 합니다. FB에서 이상민님이 TYPE_640x480으로 의견 주셨는데, 요건 좋은 것 같아요. 이렇게 쓰면 약간의 중복이 있어보이긴 합니다만, nested function까지는 안 써도 될 것 같네요.

2013-03-20 09:29

@민달 아무리 시시각각 변화한다고 하지만 이렇게 기본이 되는 Type까지 변화할 가능성을 고려해서 TYPE1, TYPE2로 대응하는 것은 너무 소극적인 대응이 아닌가라는 생각을 합니다. 지금과 같은 생각을 하게 되는 원인을 찾아보면 이 정도로까지 소극적인 대응을 하도록 만드는 현재 조직의 문화적인 문제가 있을 것이라는 생각이 드네요. 이 코드에 대한 생각 하나만 보더라도 조직의 문화가 대략적으로 그려질 수 있다는 생각이 드네요.

앞으로 소스 코드를 보고 어떤 방식으로 접근하는지 보면서 그 친구 조직이 어떤 생각을 하고, 그 친구가 어떤 조직에서 생활해 왔는지를 유추해 보는 것도 재미있겠네요. 암튼 이 정도로까지 변화에 소극적으로 대응해야할 것인지는 아직도 미지수입니다.

2013-03-20 10:23

@자바지기 저도 박교수님^^ 의견에 공감을 눌렀습니다. ㅋ 가정을 기술하고 미래(?)를 검토해보았습니다. ㅋ " 해당 썸네일은 넓이 640 이하에서 혹은 1080이하에서 사용한다는 현재의 규칙(언제든 바뀌어도 이상치 않은)이고, 어떤 관점에서는 Use Case에 가깝다는 생각이 들었습니다 " * 변경에 대해서는 우리는 타입을 추가하는 것으로 일반적으로 대응합니다. * 또한, 우리는 Use Case에서 명사를 도출하고 그 도출된 용어가 도메인 이름이 됩니다. 이런 관점에서 Use Case를 통한 네이밍은 부자연 스럽지 않은 프로그램밍이라고 생각됩니다.

오히려 코드로 명확하게 표현하고 더 이상 명확하고 짧게 용어를 도출하지 못 한 경우에 우리는 내가 만든 코드의 설명을 위해 java doc을 사용합니다. 이를 통해 나의 코드를 보는(쓰는) 사람으로 하여금 협업 코드 가능한 rich interface(다른 뜻 으로 사용되지만, 차용^^)를 제공한다고 판단 됩니다.

현재의 enum 이름이 타 개발자에게 rich하게 제공되고 있는지 검토해봐야 할 듯 합니다. code는 나를 위해서 작성하는 것이 아니라 타 개발자를 위해서 작성하는 것이 가장 중요한 포인트라고 생각합니다.

2013-03-20 10:53

저는 코드 구조가 약간 복잡해져도 가독성을 획득할 수 있다면 그렇게 불편하지는 않던데 ... 그래서 민달패턴이 저에겐 귀엽고 좋은데요? 그런데 왜 objective-c 코드는 보기 불편하지? @@

다만 저런 식으로 enum을 사용하는 것이 좋은지는 확신이 없네요. 자동화를 위해서는 width, height에 의한 배너이미지 네이밍도 결정이 될테고 ...

class Banner {
    Banner(int width, int height) { ... }
    Sring url() { return "banners/b_" + width + "_" + height; }
    static Banner for640() { return new Banner(292, 242); }
    static Banner for1280() { return new Banner(594, 480); }
}


class BannerTest {
   @Test public void 가로길이_틀리면_안됌() {
       assertEquals(292, Banner.for640().width());
       assertEquals(594, Banner.for1280().width());
   }
}

끝으로 비즈니스가 바뀔 때, 요구사항을 제대로 반영하기 위한 코드 변경과정은 당연하다고 생각하고 그 비용이 저렴하다면 flexibility가 떨어져도 된다고 생각합니다. simplicity를 강하게 추구해서 얻을 수 있는 이득에는 변경에 대한 대응력과 가독성도 포함될테니까요. 너무 간단하게 세미콜론 하나로 끝내는 수준의 코드만 아니라면요.

답변하고 보니 주제와는 약간 동떨어졌네요.

의견 추가하기

연관태그

← 목록으로