Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

계층 간 인터페이스 추가 및 유스케이스 분리 완료 #399

Merged
merged 108 commits into from
Jul 7, 2024

Conversation

limehee
Copy link
Collaborator

@limehee limehee commented Jul 4, 2024

Summary

#392

헥사고날 아키텍처로 전환하기 위해 계층 간 결합도를 낮추고 유스케이스 별로 비즈니스 로직을 분리하는 작업을 수행하였습니다. 이는 코드의 유연성을 높이고 유지보수를 용이하게 하기 위함입니다. 다음과 같은 작업을 통해 애플리케이션의 확장성과 유지보수성을 높였습니다.

Tasks

  • 계층 간 인터페이스 추가

    • 도메인 간의 직접적인 의존성을 인터페이스로 대체
    • 각 계층에서 사용할 인터페이스 정의 및 이를 구현하는 클래스 작성
    • 인터페이스를 통해 계층 간의 통신을 추상화하고 구현체를 주입하여 사용
  • 유스케이스 분리

    • 비즈니스 로직을 유스케이스 별로 분리
    • 유스케이스를 독립적인 클래스로 정의하고 필요한 의존성을 주입받아 사용

실행 흐름

  • Controller: 사용자 인터페이스나 API를 통해 들어오는 요청을 처리합니다.
  • UseCase: 비즈니스 로직을 담당하는 유스케이스(인바운드 포트)를 호출합니다.
  • Service/Domain: 비즈니스 로직이 실제로 수행되는 서비스나 도메인 모델입니다.
  • Port: 도메인 모델이 외부 시스템과 상호작용하기 위해 사용하는 인터페이스입니다. 아웃바운드 포트가 여기에 해당됩니다.
  • Adapter: 포트를 구현하여 실제 외부 시스템과 상호작용하는 어댑터입니다. 아웃바운드 어댑터가 여기에 해당됩니다.

패키지 구조

domain
├── api
│   ├── 유스케이스별 컨트롤러가 포함됩니다. 각 컨트롤러는 특정 유스케이스를 처리하는 엔드포인트를 제공합니다.
├── application
│   ├── port
│   │   ├── in
│   │   │   ├── 인바운드 포트 인터페이스를 정의합니다. 애플리케이션 외부에서 들어오는 요청을 처리하는 역할을 합니다.
│   │   ├── out
│   │   │   ├── 아웃바운드 포트 인터페이스를 정의합니다. 애플리케이션 내부에서 외부 시스템이나 데이터베이스로의 요청을 처리하는 역할을 합니다.
│   ├── service
│   │   ├── 인바운드 포트 인터페이스를 구현하는 서비스 클래스들이 위치합니다. 비즈니스 로직을 구현하고, 필요한 경우 아웃바운드 포트를 호출합니다.
├── dao
│   ├── 영속 계층과 아웃바운드 포트 인터페이스의 구현체를 포함합니다. 데이터베이스와의 상호작용을 처리합니다.

파일 네이밍 규칙

  • Controller, Service, Adapter

    • 파일명: 명사 + Controller, Service, Adapter
    • 표준 관행에 따라, 명사로 파일 이름을 작성합니다.
    • 명사를 사용하면 해당 클래스나 파일이 어떤 개념이나 도메인 객체를 나타내는지 더 명확하게 표현할 수 있습니다.
  • Inbound | Outbound Port

    • 파일명: 동사 + UseCase, Port
    • 포트는 구현이 아닌 동작을 정의하는 인터페이스이므로, 동사로 시작하는 이름을 통해 이들이 실제로 수행해야 하는 작업이나 역할을 강조합니다.

CRUD 작업 분류에 따른 네이밍 규칙

  • Create
    • Register
  • Read
    • Retrieve
    • Retrieval
  • Update
    • Update
    • Toggle
  • Delete
    • Remove

파일 분리 규칙

모든 분리는 단일 책임 원칙모듈화, 확장성, 코드 탐색 용이성을 고려합니다.
아래는 프로젝트 내에서 보편적으로 적용되는 규칙이며, 도메인의 복잡성이 높아지는 경우 CQRS 등을 적용할 수 있습니다.

  • Controller, Service, Inbound Port

    • 유스케이스별로 파일을 분리합니다.
    • 각 유스케이스에 대한 책임이 명확히 분리하며, 새로운 유스케이스가 추가될 때, 기존 코드에 영향을 주지 않고 쉽게 추가할 수 있습니다.
    • 유스케이스별로 분리된 파일은 테스트를 더 쉽게 만듭니다. 각 유스케이스에 대해 독립적으로 테스트할 수 있어 테스트의 신뢰성과 효율성이 높아집니다.
    • 여러 개발자가 동시에 작업할 때 충돌을 최소화할 수 있습니다. 각 개발자가 별도의 유스케이스에 대해 작업할 수 있어 병렬 개발이 용이해집니다.
  • Outbound Port

    • CRUD별로 파일을 분리합니다.
    • 아웃바운드 포트는 외부 시스템과의 상호작용을 담당합니다. CRUD 작업(Create, Read, Update, Delete)별로 포트를 나누면 각 포트가 수행하는 기능이 명확해집니다.
    • CRUD 작업별로 분리된 포트는 여러 유스케이스에서 재사용될 수 있으며, 특정 CRUD 작업에 대한 변경이 필요할 때, 해당 포트만 수정하면 되므로 유지보수가 용이합니다.
  • Adapter

    • 도메인별로 파일을 분리합니다.
    • 도메인당 하나의 어댑터를 사용하면 변경이 필요할 때, 특정 도메인의 어댑터만 수정하면 되므로, 다른 도메인에 영향을 미치지 않습니다.
    • 각 도메인과 외부 시스템 간의 상호작용을 독립적으로 관리할 수 있습니다. 이는 도메인 간의 결합도를 최소화하여, 한 도메인의 변경이 다른 도메인에 미치는 영향을 줄입니다.
    • 도메인당 하나의 어댑터를 사용하면, 새로운 도메인이나 기능이 추가될 때 기존 어댑터를 수정할 필요 없이, 새로운 어댑터를 추가하여 확장할 수 있습니다.

다른 도메인에 대한 접근

다른 도메인의 접근이 필요할 시 인바운드 포트를 이용합니다.

  • 도메인 간의 직접적인 의존성을 피하고 인바운드 포트를 사용하면, 한 도메인의 변경이 다른 도메인에 영향을 미치지 않도록 할 수 있습니다.
  • 인바운드 포트는 인터페이스이므로, 인터페이스 자체가 크게 변경되지 않는 한, 구현체가 변경되더라도 이를 사용하는 다른 도메인에는 영향을 주지 않습니다.
  • 도메인 간의 의존성을 인터페이스를 통해 역전시킴으로써, 고수준 모듈이 저수준 모듈에 의존하지 않게 됩니다.

ETC

  • 활동 관련 도메인은 재설계할 예정이기 때문에 해당 작업에 포함되지 않았습니다.

limehee added 30 commits June 29, 2024 16:58
@limehee limehee self-assigned this Jul 4, 2024
@limehee limehee linked an issue Jul 4, 2024 that may be closed by this pull request
@limehee limehee added the 🔨 Refactor 코드 수정 및 개선 label Jul 4, 2024
@mingmingmon
Copy link
Collaborator

PR 설명이 구체적이어서 이해하기 좋았습니다!
확실히 인터페이스 정의와 구현을 통해 유지보수가 편리해 진 것 같습니다.

프로젝트가 거대해지면서 코드 관리를 위해 아키텍처를 수정하는 것이 필요하다는 것을 배웠고,
이후에 함께할 테스트 코드 작업이 기대됩니다!

@limehee
Copy link
Collaborator Author

limehee commented Jul 5, 2024

리뷰 감사합니다. 추가적인 개선이 필요하거나 더 좋은 방법이 있으면, 의견도 같이 남겨주시면 감사하겠습니다.

@limehee limehee closed this Jul 5, 2024
@limehee limehee reopened this Jul 5, 2024
@SongJaeHoonn
Copy link
Contributor

코드를 보니 원래 통합되어 있던 메소드들이 하나하나 따로따로 분리되어 SRP에 엄청나게 힘을 주신 것이 눈에 보이네요.
더욱 클래스들이 많아져서 아직은 이해하기 힘들 것 같지만, 다른 도메인에 대한 의존성이 사라져 유지보수에 큰 도움이 될 것 같습니다.
변경점이 너무 많아서 점차 하나하나 확인하며 좋은 의견 있으면 말씀드리겠습니다.

@limehee
Copy link
Collaborator Author

limehee commented Jul 5, 2024

단일책임원칙 준수와 계층 간 결합을 최소화에 중점을 두고 대규모 작업을 진행했는데, 이번 작업의 핵심을 알아봐주셔서 감사할 따름이네요. 변경점이 많아 일일이 확인하기 번거롭겠지만, 천천히 검토하면서 피드백 주시면 적극 반영하겠습니다.

@limehee limehee merged commit 3fe57d0 into develop Jul 7, 2024
2 checks passed
@limehee limehee deleted the refactor/#392 branch July 7, 2024 14:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🔨 Refactor 코드 수정 및 개선
Projects
None yet
Development

Successfully merging this pull request may close these issues.

계층 간 인터페이스 추가 및 유스케이스 분리
3 participants