패키지 구조는 어떻게 가져가는 것이 좋을까?

2012-11-27 13:57

패키지 구조와 관련해 끊이지 않는 논쟁 거리가 있는데 오늘은 그 이야기를 함 해보자. 이 또한 상황에 따라 다르다고 할 수도 있겠지만 나름의 이유는 있어야 된다고 생각한다.

layered architecture 기반으로 개발한다고 가정하고 이야기를 전개해 보자. 각 layer별 패키지명은 다음과 같이 진행하기로 결정했다. 도메인 클래스는 domain, 비지니스 레이어는 service, 퍼시스턴스 레이어는 dao, 프리젠테이션 레이어는 web과 같이 명명하기로 약속했다. 이 명명 규칙은 각 프로젝트마다 다르게 정할 수 있다. 하지만 이슈는 이것이 아니라 그 다음이다. 패키지 구조에서 각 layer와 모듈의 관계를 어떻게 가져갈 것인가가 그 이슈이다.

1안 - layer 우선

  • net.slipp.domain.modulename
  • net.slipp.service.modulename
  • net.slipp.dao.modulename
  • net.slipp.web.modulename

2안 - 모듈 우선

  • net.slipp.modulename.domain
  • net.slipp.modulename.service
  • net.slipp.modulename.dao
  • net.slipp.modulename.web

위 두 가지 안 중 어느 방법이 더 좋을까? 내가 생각하는 각각의 장단점을 살펴보면 다음과 같다.

1안

  • 특징
    • 도메인 모델 위주 개발에 적합하다.
  • 장점
    • 각 패키지간의 cyclic dependency가 발생할 가능성이 적어진다.
    • 중복된 부분을 제거하기 용이하다.
  • 단점
    • 추후 모듈 단위로 분리할 때 어려움이 있다.

2안

  • 특징
    • 개발자별로 기능 단위 개발을 하는 경우 주로 발생한다.
  • 장점
    • 모듈 단위로 분리할 때 유리하다.
  • 단점
    • 각 패키지간에 cyclic dependency가 발생할 가능성이 높다.
    • 각 모듈에 중복된 코드가 발생할 가능성이 높다.
    • 도메인 간의 관계보다 각 모듈별로 각자 구현할 가능성이 높다.

나는 위 같은 특성 때문에 패키지 구조를 결정할 때 1안을 사용한다. 최초 패키지 구조 잡을 때 2안에 대한 강한 애정을 가지는 개발자들이 많아서 이들을 설득하는데 애를 먹는 경우가 종종 있다. 2안도 좋지만 그 단점을 고려했을 때 1안이 더 나은 선택이지 않을까 생각해본다.

각자 패키지를 잡는 방법은 어떻게 되는지 궁금하다. 또한 내가 위에서 제시한 1안과 2안의 장,단점에서 잘못 생각하고 있는 부분이 있을까?

7개의 의견 from SLiPP

2012-12-01 14:22

저는 1안으로 개발을 해놨다가 패키지가 많아지면서 코드쫓기에 불편함을 느끼게 되었습니다. (모듈이 늘어나면 늘어날수록 마우스 드래그가 빈번해지고 작업시간이 많아지면 점차 눈의 피로와 함께 저 패키지들 쫓기가 여간 귀찮은게 아니어서요... 패키지들 막 열려있고 view code들 왔다갔다하면 집중도 흐려지구요 ㅠ) 그래서 2안으로 패키징작업을 했습니다. ㅎㅎ;;; 다른 이유보다도 그냥 저 편하자고.... -_-;;;

좀 이상한 코딩인지는 모르겠으나 특정 모듈에서 전 layer를 다 거치는 enum 클래스와 Service layer에서 생성되어 view layer로 전달되는 data set object(?)를 여럿 만들었는데 이를 2안으로 패키징후에 작업하니 코드관리하기가 편리하였습니다. (net.slipp.modulename.enumPack / net.slipp.modulename.Service.DataObj) 이렇게 작업을 해놨는데 맞을까요 ㅎㅎ;;;)

여기서 질문을 드리자면 1안으로 패키지작업시 모듈에 종속되는 Enum 클래스를 만들때에 어떤 패키지에 넣어주어야하며(Enum 클래스를 만드는 것도 맞는걸까요?), Service layer에서 Model 로부터 넘어온 data 가공에 필요한 data set 을 위한 object 를 만드는 일이 옳을까요?

2012-12-01 14:35

예전에도 한참 고민하던 적이 있었는데, 특별한 정답은 없다는 결론을 내리고는 잊어 버리고 있었습니다. 마침, 이 글을 읽고 며칠간 머릿속에 두고 곰곰히 생각해 봤습니다. 자연적인 형태의 것들을 트리로 옮겨야만 할 때, 가장 중요한 것이 무엇일까 생각해 보았습니다. 보통 모듈화의 편의성 때문에 2안을 따랐지만, 1안도 적극적으로 시도해 보려고 합니다. 좋은 글 감사합니다.

2012-12-01 21:22

@김문수 enum 클래스야 필요한 경우 종종 만들어서 사용한다. 일반적으로 domain(또는 model 이라고 해야 하나)에서 관리한다. 내가 생각하는 enum과 정확하게 일치하는지는 이후에 소스 코드를 봐야지 알겠는데. enum을 사용하는 경우는 많지 않아서... 그리고 일반적으로 패키지에는 대문자를 사용하지 않는다.

Service layer의 DataObject는 우리들이 일반적으로 이야기하는 Data Transfer Object라는 생각이 드는데 맞는 것인가? 이와 관련해서는 의견이 분분한데 상황에 따라 필요할 수도 있고, 그렇지 않을 수도 있을 듯 하다. 뭐 반드시 만들어야 될 이유는 없을 듯하다. 모든 것이 상황에 따라 필요하고 필요하지 않을 수 있기 때문에..

추후에 소스 코드 함 보여주라. 그럼 더 많은 이야기 나눌 수 있을 듯하다.

2012-12-01 21:25

@최정열 상황에 따라 2안을 선택할 수도 있다고 생각합니다. 하지만 1안에 대해서도 고민해 볼 필요는 있다고 생각합니다. 이는 프로젝트가 현재 구조로 그대로 유지한다면 모르겠지만 추후 여러 개의 모듈로 분리될 때 이슈가 된다고 생각합니다.

예를 들어 모듈을 분리할 때 layer 별로 분리하는 경우라면 1안이 더 유리하겠죠. 만약 모듈별로 분리된다면 2안이 더 유리할 것으로 생각됩니다. 하지만 모듈을 분리할 때 각 패키지간에 cyclic dependency가 없는 상태라야 분리가 용이할 것입니다. 그런 관점에서 볼 때 cyclic dependency가 발생할 가능성이 적은 1안이 미래의 변경 가능성에 더 쉽게 대응할 수 있지 않을까 생각합니다.

2012-12-18 14:23

설계가 잘되어 있고, 모듈 활용에 대한 강력한 통제 이루어지고,

개발자들이 잘 따라오는 프로젝트 라면 1안이 좋을 것 같습니다.

하지만 개발자(또는 업체)가 자주 바뀌고 교육도 잘 안되거나 규모가 커져서

컨트롤이 힘들어지는 프로젝트라면 차라리 2안으로 가는게 더 나을 것같습니다.

2017-08-24 22:14

저도 예전에 자바지기님과 같은 고민을 한적이 있었습니다. 혼자하는 프로젝트도 그렇고 여럿이 하는 프로젝트도 그렇고 기능단위 패키지 분리가 개발 피로도를 비약적으로 낮춰주기 때문에 선호합니다.

의견 추가하기

연관태그

← 목록으로