Skip to content

[1주차] 아키텍처 설계#16

Open
soyoungcareer wants to merge 12 commits intohanghae-skillup:mainfrom
soyoungcareer:week1
Open

[1주차] 아키텍처 설계#16
soyoungcareer wants to merge 12 commits intohanghae-skillup:mainfrom
soyoungcareer:week1

Conversation

@soyoungcareer
Copy link

작업 내용

테이블 구조

erd
테이블 : 영화, 장르, 상영관, 상영시간표, 좌석, 회원, 예매

  • 영화 썸네일 이미지는 URL로만 사용하므로 편의상 파일 테이블을 따로 생성하지 않음.
  • 공통코드는 공통코드 테이블을 생성하지 않고 ENUM으로 관리함. (영상물 등급, 좌석유형)

아키텍처(Hexagonal Architecture)

  • cinema-core

    => 도메인, 엔티티, 비즈니스 로직

    • 비즈니스 로직의 중심으로, 외부 변화에 의존하지 않도록 설계.
    • 영화, 상영 시간표 등의 도메인 모델과 관련 규칙 정의.
  • cinema-application

    => 유스케이스(Use Case)

    • 도메인 로직을 호출하고 조합하여 시스템의 흐름을 관리.
    • 입력(사용자 요청)과 출력(결과 반환)을 조정.
  • cinema-adapter

    => (Inbound) REST Controller, CLI

    • 사용자나 외부 세계의 요청을 애플리케이션에 전달.

    => (Outbound) JPA Repository, External API

    • 애플리케이션의 요청을 외부 시스템(DB, API 등)으로 전달.
  • cinema-infra

    => DB 연결, 외부 라이브러리 설정

    • 기술적인 환경과 세부 설정을 처리.
  • cinema-common

    => 공통으로 사용할 수 있는 유틸리티, 상수, 예외 처리 클래스

    • 도메인 및 유스케이스와 독립적인 범용 코드를 관리.
    • 비즈니스 로직과 관련 없는 코드만 포함하여 비대화 방지.

외부 변화에 대한 의존성을 최소화하기 위하여 Domain 관련한 부분은 cinema-core 모듈로 생성하였음.
cinema-application은 전체 시스템의 흐름과 연결을 관리하며 도메인 로직을 호출하고 조합하여 유스케이스(사용 시나리오)를 처리함.
cinema-adapter은 외부 세계와 연결하는 모듈로서 역할을 하며, 입력(Inbound)과 출력(Outbound)으로 나뉨.
또한, Port를 구현하여 cinema-application이 도메인과 외부 시스템을 매끄럽게 조작할 수 있도록 도움.
cinema-infra는 기술적인 환경을 세팅하는 모듈로 데이터베이스 연결 설정, 외부 라이브러리 설정 등을 함.
cinema-common 모듈은 공통으로 사용할 수 있는 유틸을 묶어두어 범용성 있게 구성하였음.
단, 모듈이 비대해지고 강결합이 발생하지 않도록 변화가 적으며 비즈니스 로직과 관련 없는 코드만 사용하도록 명확히 하여야 함.

발생했던 문제와 해결 과정을 남겨 주세요.

  • 애플리케이션 실행 시 다음과 같은 오류 발생하여 정상적으로 실행되지 않음.
***************************
APPLICATION FAILED TO START
***************************

Description:

Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.

Reason: Failed to determine a suitable driver class


Action:

Consider the following:
        If you want an embedded database (H2, HSQL or Derby), please put it on the classpath.
        If you have database settings to be loaded from a particular profile you may need to activate it (no profiles are currently active).

-> compose.yaml, application.yml 파일을 수정해보았으나 해결하지 못하였음. Docker compose 실행은 정상적으로 되는 상태이나 app url 연결에 문제가 발생하는 것으로 보임.


이번 주차에서 고민되었던 지점이나, 어려웠던 점을 알려 주세요.

  • 아키텍처 설계 및 설정 등을 처음해봐서 시간이 오래걸렸고 어렵게 느껴졌습니다.

리뷰 포인트

  • 헥사고날 아키텍처로 설계하고자 하였는데, 적절한 방식으로 설계하였는지에 대한 피드백
  • 테이블 구조와 엔티티 설정 부분이 적절하게 되었는지에 대한 피드백

기타 질문

  • .env 파일에 설정하는 보안이 필요한 정보 같은 경우 git에 올리지 않고 사용할텐데 민감정보에 대해서는 보통 어떤식으로 관리하여 사용하는지 궁금합니다.

@DongHyunKIM-Hi
Copy link

안녕하세요 열심히 임해주신 것에 대해서 저도 좋은 자극을 받았음에 감사하면 코드 리뷰 시작하겠습니다.
우선 기타 질문에 먼저 답을 드리자면 .env 값의 경우에 깃헙 프로젝트 별로 secretKey로 설정하여 값을 코드와 분리 시킬수가 있습니다.
해당 방법 외에도 만약에 단일 ec2 환경에서 사용한다고하면 EC2 컴퓨터 내부에 환경변수로 값들을 설정하여 불러오는 방식으로도 사용하기도 합니다.

public class MovieController {
private final MovieService movieService;

public MovieController(MovieService movieService) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

root 프로젝트에서 lombok 디펜던시를 추가했던데 굳이 @requiredargsconstructor를 사용하지 않고 생성자로 만들어서 사용한 이유가 있을까요? 어떤 것을 사용하든 상관은 없지만 개인적으로는 가독성적인 측면에서 @requiredargsconstructor 를 사용하는 것이 좀 더 깔끔하다고 생각이 들어요!
멀티 모듈에서 해등 모듈의 롬복이 없는 것도 아니라서요!

this.movieService = movieService;
}

@GetMapping("/bookable")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

URL의 자원을 명사로 표기하는 것을 권장하고 있습니다.
예약 가능 여부는 query parameter로 구분: /api/movies?bookable=true
이런 식으로 표기하는 것이 좀 더 좋지 않을까? 싶습니다. 이후 확장성 측면에서도 유리할 것 같아 보입니다.


@CreatedDate
@Column(name = "reg_dttm", nullable = false, updatable = false)
private LocalDateTime regDttm;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

컨벤션을 어떻게 설계하느냐에 따라 다르지만 개인적으로는 축약어를 사용하는 것을 지양하는 것이 좋을것 같아요. 새로운 팀원이 들어오거나 기존의 인원이 아닌 사람이 코드를 수정하거나 작업할 때 이런 축약어 제한을 풀어두면 코드가 점점 가독성이 떨어질 가능성이 있기 때문에 개인적으로는 선호 하지는 않아요.

@Column(name = "reg_dttm", nullable = false, updatable = false)
private LocalDateTime regDttm;

@Column(name = "chg_user_id")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JPA 컨벤션은 카멜 케이스로 작성된 코드를 스네이크 코드로 변경 시켜주는 것이 디폴트 설정으로 잡혀 있어요. 그래서 굳이 불필요한 코드를 작성할 필요가 없습니다!

또한 위에서도 언급했지만 제가 처음 봤을 때 chg 라는 축약어가 뭔지 몰라서 불필요하게 구조를 뜯어보고 어떤 의미인지 유추하게 되었는데 이런 요소들은 생산성을 저하 시킬 원인이 되기도 합니다! 한번 고려해주시면 좋을 것 같아요!

private Long seatId;

@Column(name = "seat_type_cd")
private String seatTypeCd;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이후에는 이런 값들은 enums로 관리되면 더 좋겠죠?

ddl.sql Outdated
`CHG_USER_ID` VARCHAR(20) NULL COMMENT '수정자',
`CHG_DTTM` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '수정일',
PRIMARY KEY (`BOX_ID`)
DROP TABLE IF EXISTS `box`;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

네이밍을 좀 더 명확한 의미의 단어를 사용하는 것이 더 좋을 것 같아요. Cinema, Theater 같이 말이죠! box 라는 단어를 극장이라고 사용하기는 하는데 일반적으로 사용하지는 않아서 헷갈리수도 있을 것 같아요.

ddl.sql Outdated
`CHG_USER_ID` VARCHAR(20) NULL COMMENT '수정자',
`CHG_DTTM` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '수정일',
PRIMARY KEY (`TIME_ID`)
DROP TABLE IF EXISTS `timetable`;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

스케쥴이라는 단어가 더 맞지 않을까? 혹시 스케쥴이 예약어라 사용하지 못한것이라면 movie_scheule 이라고 작성하는 것이 좀 더 의미가 명확하게 전달 될 것 같아요.

@DongHyunKIM-Hi
Copy link

DongHyunKIM-Hi commented Jan 12, 2025

좋았던 점

  • 처음 하는 개념인데 설정이랑 구조에 대해서 많은 고민을 하신것 같아서 좋았습니다.
  • 헥사고날 아키텍쳐에서는 도메인 모듈에서는 순수 자바 객체만을 사용해서 구현하는 것이 원칙이긴 하지만 이렇게 될 경우 다른 외부 기술 변경으로 인한 코드 수정에 대한 불편함 보다 infra 모듈에서 설정된 entity 객체과 도메인 모듈에서 설정된 entity dto 객체의 변환으로 인한 비용 발생이 더 클 수도 있습니다. 이런 부분을 염두하여 현재 구조로 설계했것 같아 보여 좋았습니다. 물론 객체 변환 비용을 mapstruct 라는 것을 통해서 자동화 시켜서 관리 할 수도 있지만 이것 또한 외부 기술에 의존하는 것이라 생각해볼 여지가 있을 것 같습니다.

아쉬웠던 점

  • 설계를 했는데 아직 코드 구현이 안된 것이 아쉬웠습니다.
    그래서 현재 설계하고 구상하고 있는 내용에 대해서 명확하게 이해 할 수 없었습니다.
  • 이후 좀 더 고도화 되겠지만 현재 작성되어 있는 내용으로만 봐서는 controller -> service -> repository 구조의 레이어 아키텍처로 보여질수도 있을 것 같다는 생각이 문득 드네요 ㅠㅠ
  • 디비 컬럼 및 컨벤션을 통일이 안된 부분에서 같이 일하는 사람들의 불필요한 커뮤니케이션 비용이 발생할 것 같다는 생각이 들었습니다.

총평

이카텍처가 잘 구성되어 었는지는 현재 구조로는 알기가 쉽지 않을 것 같아요. 현재 작성된 코드가 api/movie/bookable 만 있어서 다른 케이도 작성되어야 소영님이 의도한 것이 어떤 것인지 확인이 가능할 것 같습니다. DB 구조를 보니까 어떤 곳은 date, time 이런 것을 사용하고 있고 다른 곳에서는 dttm 같은 축약어도 사용하고 있어요. 해당 컬럼의 구조는 통일해주는 것이 좋을 것 같아요.

@phyeran phyeran changed the base branch from main to soyoungcareer January 17, 2025 02:08
@spartacontents spartacontents deleted the branch hanghae-skillup:main January 17, 2025 03:20
@phyeran phyeran changed the base branch from soyoungcareer to main January 19, 2025 06:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants