계층으로 구성하기

buckpal
|----domain
|     |--Account
|     |--Activity
|     |--AccountRepository
|     |--AccountService
|----persistence
|     |--AccountRepositoryImpl
|----web
      |--AccountController

의존성 역전을 위해 domain 패키지에 AccountRepository를 추가하고, persistence 패키지에 AccountRepositoryImpl을 추가했다.

다만 위 패키지 구조는 적어도 세 가지 이유로 최적의 구조가 아니다.

  1. 애플리케이션의 기능 조각(functional slice)이나 특성(feature)을 구분짓는 패키지 경계가 없다.

    1. 만약 사용자 기능이 추가된다면 UserController, UserService, UserRepository 등의 코드가 추가되는데, 이러면 연관되지 않은 기능들끼리 한 패키지에 있어 예상치 못한 부수효과를 일으킬 수 있다.
  2. 애플리케이션이 어떤 유스케이스들을 제공하는지 파악할 수 없다.

    1. AccountService와 AccountController가 어떤 유스케이스를 구현했는지 알 수 없어, 특정 기능을 찾기 위해서는 어떤 서비스가 이를 구현했는지 추측해야 한다
  3. 패키지 구조를 통해서는 목표로 하는 아키텍처를 파악할 수 없다.

    1. 헥사고날 아키텍처인 것은 추측할 순 있겠지만, 웹 어댑터와 영속성 어댑터를 찾기 위해 클래스들을 조사해야 한다.
    2. 또한 인커밍 포트와 아웃고잉 포트가 코드속에 숨겨져 있다.

기능으로 구성하기

buckpal
|----account
     |--Account
     |--AccountController
     |--AccountRepository
     |--AccountRepositoryImpl
     |--AccountService
     |--SendMoneyService

가장 본질적인 변경은 계좌와 관련된 모든 코드를 account 패키지에 넣었다. 계층 패키지들도 없앴다.

또한 AccountService의 책임을 좁히기 위해 SendMonyService로 클래스명을 바꿨다.

→ 이로써 송금하기 유스케이스를 구현한 코드는 클래스명만으로도 찾을 수 있게 되었다.