프로젝트 및 폴더 구조

jinkyu Seok·2025년 1월 24일

기초학습

목록 보기
5/11

Q. 지금 폴더구성을 살펴보고, 프로젝트에서 폴더구성이 왜 중요한지 알려줘.

현재 프로젝트의 폴더 구조를 분석해보면 다음과 같은 계층형 구조로 되어 있습니다:

Backend/
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   └── com.example.gc_coffee/
│   │   │       ├── domain/
│   │   │       │   ├── admin/
│   │   │       │   ├── item/
│   │   │       │   └── order/
│   │   │       └── global/
│   │   │           ├── exceptions/
│   │   │           ├── springDoc/
│   │   │           └── util/
│   └── test/

폴더 구조가 중요한 이유:

  1. 도메인 주도 설계(DDD) 반영

    • domain 폴더 아래에 각 비즈니스 도메인(admin, item, order)이 명확히 구분됨
    • 각 도메인의 독립성과 응집도를 높임
  2. 관심사의 분리

    • global 폴더에서 공통 기능(예외처리, 문서화, 유틸리티)을 분리
    • 코드의 재사용성과 유지보수성 향상
  3. 계층 구조의 명확성

domain/
├── admin/
│   ├── controller/
│   ├── service/
│   └── entity/
  • 각 도메인 내부의 계층(Controller, Service, Entity) 구분
  • 의존성 방향이 명확해짐
  1. 테스트 용이성

    • test 폴더가 main 폴더와 동일한 구조를 가짐
    • 테스트 코드의 관리와 작성이 용이
  2. 확장성

    • 새로운 도메인 추가가 용이
    • 기존 코드 영향 최소화

현재 코드베이스에서 이러한 구조가 잘 적용된 예시:


        return http.build();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder(); // 비밀번호 암호화
    }

    @Bean
    public UserDetailsService userDetailsService() {
        // 관리자 계정 설정 (메모리 기반)
        UserDetails admin = User.builder()
                .username("team4@admin.com")
                .password(passwordEncoder().encode("admin_team4")) // 비밀번호 암호화
                .roles("ADMIN") // ADMIN 역할 부여
                .build();

        return new InMemoryUserDetailsManager(admin);
    }

    @Bean
    public AuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
        provider.setUserDetailsService(userDetailsService()); // UserDetailsService 연결
        provider.setPasswordEncoder(passwordEncoder()); // PasswordEncoder 연결
        return provider;
    }

    @Bean
    public AuthenticationManager authenticationManager(AuthenticationConfiguration config) throws Exception {
        return config.getAuthenticationManager(); // AuthenticationManager 설정
    }
}
  • Security 관련 설정이 admin 도메인 내부에 위치하여 관련 기능의 응집도를 높임

이러한 체계적인 폴더 구조는 프로젝트의 확장성, 유지보수성, 테스트 용이성을 크게 향상시키며, 팀 멤버들의 코드 이해와 협업을 더욱 효과적으로 만듭니다.

Q.현재 프로젝트 폴더구성의 잘못된 부분과 앞으로 프로젝트시에 필수적으로 구조화되어야 하는 부분을 알려줘

현재 프로젝트의 개선이 필요한 부분

1. Security 설정의 위치 문제

현재 위치:
domain/admin/login/SecurityConfig.java

개선안:
global/config/security/SecurityConfig.java

이유: Security는 특정 도메인이 아닌 애플리케이션 전체의 설정이므로 global 영역으로 이동해야 함

2. 도메인 내부 구조의 일관성 부재

현재:
domain/admin/
├── login/
│   ├── controller/
│   └── service/
└── service/AdminService.java

개선안:
domain/admin/
├── controller/
├── service/
├── repository/
├── entity/
└── dto/

3. global 패키지 구조 개선

현재:
global/
├── exceptions/
├── springDoc/
└── util/

개선안:
global/
├── config/           # 각종 설정 파일
│   ├── security/
│   ├── swagger/
│   └── web/
├── common/           # 공통 컴포넌트
│   ├── response/
│   └── util/
└── error/           # 예외 처리
    ├── exception/
    └── handler/

프로젝트 필수 구조화 가이드

1. 기본 패키지 구조

src/
├── main/
│   ├── java/
│   │   └── com.project/
│   │       ├── domain/          # 도메인 별 패키지
│   │       ├── global/          # 공통 설정 및 유틸
│   │       └── infrastructure/  # 외부 인프라 연동
│   └── resources/
│       ├── static/
│       └── application.yml

2. 도메인 패키지 표준 구조

domain/webtoon/
├── controller/
│   ├── WebtoonController.java
│   └── dto/
│       ├── request/
│       └── response/
├── service/
│   ├── WebtoonService.java
│   └── dto/
├── repository/
│   ├── WebtoonRepository.java
│   └── dto/
└── entity/
    └── Webtoon.java

3. global 패키지 필수 구성

global/
├── config/                    # 설정 클래스
│   ├── SecurityConfig.java
│   ├── JpaConfig.java
│   └── WebConfig.java
├── common/                    # 공통 컴포넌트
│   ├── annotation/
│   ├── response/
│   │   ├── ApiResponse.java
│   │   └── ErrorResponse.java
│   └── util/
├── error/                     # 예외 처리
│   ├── exception/
│   │   ├── BusinessException.java
│   │   └── ErrorCode.java
│   └── handler/
│       └── GlobalExceptionHandler.java
└── security/                  # 보안 관련
    ├── jwt/
    └── oauth/

4. 계층간 데이터 전달 규칙

// Controller Layer
@RestController
@RequestMapping("/api/webtoons")
public class WebtoonController {
    @GetMapping("/{id}")
    public ApiResponse<WebtoonResponse> getWebtoon(@PathVariable Long id) {
        WebtoonDto webtoonDto = webtoonService.getWebtoon(id);
        return ApiResponse.success(WebtoonResponse.from(webtoonDto));
    }
}

// Service Layer
@Service
public class WebtoonService {
    public WebtoonDto getWebtoon(Long id) {
        Webtoon webtoon = webtoonRepository.findById(id)
            .orElseThrow(() -> new BusinessException(ErrorCode.WEBTOON_NOT_FOUND));
        return WebtoonDto.from(webtoon);
    }
}

5. 테스트 코드 구조

test/
├── java/
│   └── com.project/
│       ├── domain/
│       │   └── webtoon/
│       │       ├── controller/
│       │       ├── service/
│       │       └── repository/
│       └── common/
└── resources/
    └── application-test.yml

주요 개선 포인트

  1. 명확한 레이어 구분

    • Controller, Service, Repository 각각의 역할과 책임을 명확히 분리
    • 각 레이어별 적절한 DTO 사용
  2. 일관된 응답 형식

public class ApiResponse<T> {
    private final boolean success;
    private final T data;
    private final ErrorResponse error;
}
  1. 체계적인 예외 처리
public enum ErrorCode {
    WEBTOON_NOT_FOUND(404, "W001", "웹툰을 찾을 수 없습니다."),
    INVALID_REQUEST(400, "C001", "잘못된 요청입니다.");
    // ...
}
  1. 환경 설정 분리
# application.yml
spring:
  profiles:
    active: local

# application-local.yml
# application-dev.yml
# application-prod.yml

이러한 구조화를 통해 코드의 가독성, 유지보수성, 테스트 용이성이 크게 향상될 것입니다.

0개의 댓글