본문 바로가기
멋쟁이사자처럼 동아리/공통피드백

6주차 Spring core

by PlusUltraCode 2024. 6. 22.

공통 피드백

DAO vs Repository

DAO(Data Access Object)와 Repository의 차이점은 역할과 관심사에서 비롯됩니다.

  • DAO: 데이터 영속성 관점에서 DB에 직접 접근하는 객체입니다.
  • Repository: 도메인 개체 모음을 추상화한 객체로, 도메인 관점에서 도메인 객체의 집합을 다룹니다.
plaintext
코드 복사
DAO: 데이터 영속성을 추상화 Repository: 도메인 개체 모음을 추상화

DAO

Repository


DTO의 역할과 의미

DTO(Data Transfer Object)는 계층형 아키텍처에서 의존도를 끊어주는 효과가 있습니다.

예시:

 
class Reservation {
    private final String name;  // ex. "Kevin Preston"
}​

새로운 요구사항: 예약자의 성과 이름을 구분해서 저장

class Reservation {
    private final String firstName;  // ex. "Preston"
    private final String secondName;  // ex. "Kevin"
}

DTO를 사용하면 도메인 객체와 데이터 전송 객체를 분리하여 변경의 영향도를 줄일 수 있습니다.

// 중복 코드로 보이지만 역할이 다름
class SaveReservationRequest {
    private String name;
    private String date;
}

class UpdateReservationRequest {
    private String name;
    private String date;
}

NamedParameterJdbcTemplate, SimpleJdbcInsert

보다 안전하고 유지보수하기 쉬운 방법을 찾기 위해 NamedParameterJdbcTemplate과 SimpleJdbcInsert를 사용할 수 있습니다.

NamedParameterJdbcTemplate

private final JdbcTemplate jdbcTemplate;
private NamedParameterJdbcTemplate namedParameterJdbcTemplate;

public ReservationRepositoryImpl(JdbcTemplate jdbcTemplate) {
    this.jdbcTemplate = jdbcTemplate;
    this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate);
}

// NamedParameterJdbcTemplate 사용 예시
public Reservation save(Reservation reservation) {
    String sql = "INSERT INTO reservation (name, reservation_date_time) VALUES (:name, :date, :time)";
    SqlParameterSource namedParameters = new BeanPropertySqlParameterSource(reservation);
    GeneratedKeyHolder keyHolder = new GeneratedKeyHolder();
    namedParameterJdbcTemplate.update(sql, namedParameters, keyHolder);
    long generatedKey = keyHolder.getKey().longValue();
    return new Reservation(generatedKey, reservation.name(), reservation.date(), reservation.time());
}

SimpleJdbcInsert

// Before
public Reservation save(Reservation reservation) {
    String sql = "INSERT INTO reservation (name, reservation_date_time) VALUES (:name, :date, :time)";
    SqlParameterSource namedParameters = new BeanPropertySqlParameterSource(reservation);
    GeneratedKeyHolder keyHolder = new GeneratedKeyHolder();
    namedParameterJdbcTemplate.update(sql, namedParameters, keyHolder);
    long generatedKey = keyHolder.getKey().longValue();
    return new Reservation(generatedKey, reservation.name(), reservation.date(), reservation.time());
}

// After
@Repository
public class ReservationRepository {
    private final JdbcTemplate jdbcTemplate;
    private final NamedParameterJdbcTemplate namedParameterJdbcTemplate;
    private final SimpleJdbcInsert simpleJdbcInsert;

    public ReservationRepositoryImpl(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
        this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate);
        this.simpleJdbcInsert = new SimpleJdbcInsert(jdbcTemplate)
                .withTableName("reservation")
                .usingGeneratedKeyColumns("id");
    }
    
    @Override
    public Reservation save(Reservation reservation) {
        SqlParameterSource params = new BeanPropertySqlParameterSource(reservation);
        Long generatedKey = simpleJdbcInsert.executeAndReturnKey(params).longValue();
        return new Reservation(generatedKey, reservation.name(), reservation.reservationDateTime());
    }
}

리뷰

날짜/시간 형식

[Spring JDBC] 윤성원 미션 제출합니다. by mete0rfish · Pull Request #238 · next-step/spring-roomescape-playground

인터페이스(추상화)

[Spring JDBC] 김준수 미션 제출합니다. by gogo1414 · Pull Request #237 · next-step/spring-roomescape-playground

SimpleJdbcInsert

[Spring JDBC] 한상우 미션 제출합니다. by sangu1026 · Pull Request #249 · next-step/spring-roomescape-playground


Spring IoC Container

NEXTSTEP

Layered Architecture

NEXTSTEP

소프트웨어 아키텍처

소프트웨어를 구성하는 가치는 크게 두 가지로 나뉩니다:

  1. 기능
  2. 구조

우리는 기능과 구조 중 무엇에 집중해야 할까요?

소프트웨어 유지보수

어느 순간부터 유지보수 비용이 개발 비용을 초과하는 시점이 옵니다. 시간이 지남에 따라 좋은 구조를 가진 소프트웨어의 중요성이 커집니다.


계층형 아키텍처

Best Practice를 참고하여 구조를 잘 설계하는 것이 좋습니다.

  • Presentation Layer: 사용자 인터페이스(UI)와 상호 작용을 위한 계층입니다.
    • 예: 웹 페이지, 모바일 앱 화면, REST API 엔드포인트(Controller) 등
  • Application Layer: 애플리케이션의 핵심 비즈니스 규칙과 로직을 처리하는 계층입니다.
    • 예: Service
  • Persistence Layer: 데이터베이스나 다른 저장 매체와의 상호 작용을 위한 계층입니다.
    • 예: DAO

도메인과 Repository는 일반적으로 어느 계층에 속할까요?

계층형 아키텍처에서는 상위 레이어가 하위 레이어를 알고 있지만, 하위 레이어는 상위 레이어를 모릅니다. 이로 인해 하위 레이어의 변화에 취약한 구조를 지니게 됩니다.

의존성 방향과 변경에 의한 영향 전파는 반대 방향으로 흐릅니다. 따라서, 계층형 아키텍처는 DB 의존적인 설계를 할 수 밖에 없는 구조입니다.

 

'멋쟁이사자처럼 동아리 > 공통피드백' 카테고리의 다른 글

7주차. 인증  (0) 2024.06.22
5주차. 스프링 JDBC  (0) 2024.06.22
4주차. 스프링 MVC  (0) 2024.06.22
3주차. 클린코드  (0) 2024.06.22
2주차. 단위테스트  (0) 2024.06.22