5주차 Unit 3.2 — 전통 DAO의 코드

Psj·2026년 5월 27일

F-lab

목록 보기
164/239

Unit 3.2 — 전통 DAO의 코드 (모든 책임을 다 떠안은)

F-LAB JAVA · 5주차 · Phase 3 · 전통 DAO의 문제


📌 학습 목표

이 Unit을 끝내면 다음을 답할 수 있어야 한다.

  • 전통 JDBC DAO 코드의 단계 는?
  • 드라이버 로딩 / 연결 / SQL / 자원 해제 의 흐름은?
  • 한 메서드가 신경 쓰는 관심사 5개는?
  • DB 종류 변경 시 수정 범위 는?
  • 접속 정보 변경 시 수정 범위 는?
  • 메서드 간 중복 코드 는?
  • 자원 해제의 중요성 은?
  • 예외 처리의 복잡성 은?
  • 이 코드가 문제의 출발점인 이유는?

🎯 핵심 한 문장

전통 JDBC DAO 의 한 메서드는 드라이버 로딩·DB 접속·SQL 작성·파라미터 바인딩·실행·자원 해제까지 모든 책임을 떠안고 있어, 변경 한 번에 여러 곳을 수정해야 하는 유지보수 부담을 만든다.
전통 DAO 의 add() 한 메서드 안에는 (1) 드라이버 로딩, (2) DB 접속 정보 (URL·계정·비밀번호), (3) SQL 작성, (4) 파라미터 바인딩, (5) 실행, (6) 자원 해제가 모두 들어 있다.
이렇게 모든 관심사가 한 메서드에 모이면, DB 종류를 바꾸면 (MySQL → Oracle) 드라이버·URL 이 박힌 모든 메서드를 수정해야 하고, 접속 정보가 바뀌면 역시 모든 메서드를 손봐야 한다.
또한 getConnection 같은 동일한 코드가 메서드마다 반복되어 중복 이 발생하고, try-catch-finally 로 자원을 해제하는 코드가 복잡하게 얽힌다.
이 "모든 책임을 떠안은 코드" 가 바로 다음 Phase 들에서 리팩토링으로 풀어갈 문제의 출발점이다.

비유 — 모든 걸 혼자 하는 만물상

전통 DAO = 모든 걸 혼자 하는 만물상:

한 직원이 모든 일:
  1. 가게 문 열기 (드라이버 로딩)
  2. 거래처 연결 (DB 접속 + 계정/비번)
  3. 주문서 작성 (SQL)
  4. 물건 채우기 (파라미터 바인딩)
  5. 거래 실행 (executeUpdate)
  6. 정리/마감 (자원 해제)

문제:
  - 거래처 바뀌면 (DB 변경)
    → 모든 업무 매뉴얼 수정

  - 비밀번호 바뀌면 (접속 정보)
    → 모든 매뉴얼 수정

  - 같은 "문 열기" 가 매 업무마다 반복 (중복)

  - 한 명이 다 하니 복잡

→ 모든 책임이 한 곳에
→ 변경 1번 = 수정 N곳

→ 전통 DAO = 한 메서드에 모든 책임 (드라이버~자원해제), 변경 시 N곳 수정.


🧭 9개 섹션 로드맵

1. 전통 JDBC DAO 코드
2. 6단계 흐름
3. 한 메서드의 5가지 관심사
4. DB 종류 변경 시
5. 접속 정보 변경 시
6. 메서드 간 중복
7. 자원 해제
8. 예외 처리
9. 면접 + 자기 점검

1️⃣ 전통 JDBC DAO 코드

1.1 전통 add 메서드

public class ShipmentDao {
    
    public void add(Shipment shipment) throws ClassNotFoundException, SQLException {
        // ① 드라이버 로딩
        Class.forName("com.mysql.jdbc.Driver");
        
        // ② DB 접속
        Connection c = DriverManager.getConnection(
            "jdbc:mysql://localhost/ilic", "root", "password");
        
        // ③ SQL 작성
        PreparedStatement ps = c.prepareStatement(
            "insert into shipments(id, bl_no, weight) values(?, ?, ?)");
        
        // ④ 파라미터 바인딩
        ps.setLong(1, shipment.getId());
        ps.setString(2, shipment.getBlNo());
        ps.setBigDecimal(3, shipment.getWeight());
        
        // ⑤ 실행
        ps.executeUpdate();
        
        // ⑥ 자원 해제
        ps.close();
        c.close();
    }
}

1.2 모든 것이 한 곳에

한 메서드에:

  ① 드라이버 로딩
  ② 접속 정보
  ③ SQL
  ④ 바인딩
  ⑤ 실행
  ⑥ 자원 해제

  → 모든 책임

1.3 get 메서드도 유사

public Shipment get(Long id) throws ClassNotFoundException, SQLException {
    // ① 드라이버 로딩 (중복!)
    Class.forName("com.mysql.jdbc.Driver");
    
    // ② DB 접속 (중복!)
    Connection c = DriverManager.getConnection(
        "jdbc:mysql://localhost/ilic", "root", "password");
    
    // ③ SQL
    PreparedStatement ps = c.prepareStatement(
        "select * from shipments where id = ?");
    ps.setLong(1, id);
    
    // ⑤ 실행
    ResultSet rs = ps.executeQuery();
    Shipment shipment = null;
    if (rs.next()) {
        shipment = new Shipment();
        shipment.setId(rs.getLong("id"));
        shipment.setBlNo(rs.getString("bl_no"));
        shipment.setWeight(rs.getBigDecimal("weight"));
    }
    
    // ⑥ 자원 해제
    rs.close();
    ps.close();
    c.close();
    
    return shipment;
}

1.4 중복 확인

중복 확인:

  add 와 get:
    - 드라이버 로딩 (동일)
    - DB 접속 (동일)
    - 자원 해제 (유사)

  → 메서드마다 반복

1.5 자기 점검 답변

전통 JDBC DAO 코드의 단계는?

:
1. 6단계:

  • 드라이버 로딩
  • DB 접속
  • SQL
  • 바인딩
  • 실행
  • 자원 해제
  1. 한 곳에:

    • 모든 책임
  2. 중복:

    • 메서드마다 반복
  3. 출발점:

    • 문제의 시작

2️⃣ 6단계 흐름

2.1 6단계

JDBC 6단계:

1. 드라이버 로딩
   Class.forName(...)

2. 연결 (Connection)
   DriverManager.getConnection(...)

3. SQL (PreparedStatement)
   c.prepareStatement(...)

4. 파라미터 바인딩
   ps.setXxx(...)

5. 실행
   ps.executeUpdate() / executeQuery()

6. 자원 해제
   close()

2.2 각 단계 역할

각 단계:

① 드라이버: JDBC 드라이버 등록
② 연결: DB 와 연결 수립
③ SQL: 쿼리 준비
④ 바인딩: 파라미터 설정
⑤ 실행: 쿼리 실행
⑥ 해제: 연결/자원 반납

2.3 변하는 것 vs 변하지 않는 것

변하는 것 vs 변하지 않는 것:

변하지 않는 흐름 (공통):
  - 드라이버 로딩
  - 연결
  - 자원 해제

변하는 부분:
  - SQL (메서드마다)
  - 바인딩 (다름)

2.4 흐름 시각화

JDBC 흐름:

[드라이버 로딩]  ← 공통
      ↓
[연결]           ← 공통
      ↓
[SQL 준비]       ← 변함
      ↓
[바인딩]         ← 변함
      ↓
[실행]           ← 변함
      ↓
[자원 해제]      ← 공통

2.5 ILIC 의 맥락

public class ShipmentDao {
    
    public void updateStatus(Long id, String status) 
            throws ClassNotFoundException, SQLException {
        // ① 드라이버 (공통)
        Class.forName("com.mysql.jdbc.Driver");
        // ② 연결 (공통)
        Connection c = DriverManager.getConnection(
            "jdbc:mysql://localhost/ilic", "root", "password");
        // ③ SQL (변함)
        PreparedStatement ps = c.prepareStatement(
            "update shipments set status = ? where id = ?");
        // ④ 바인딩 (변함)
        ps.setString(1, status);
        ps.setLong(2, id);
        // ⑤ 실행 (변함)
        ps.executeUpdate();
        // ⑥ 해제 (공통)
        ps.close();
        c.close();
    }
    // 공통 부분이 매번 반복
}

2.6 자기 점검 답변

드라이버 로딩 / 연결 / SQL / 자원 해제의 흐름은?

:
1. 6단계:

  • 드라이버 → 연결 → SQL
  • → 바인딩 → 실행 → 해제
  1. 각 역할:

    • 등록/수립/준비/설정/실행/반납
  2. 변함 vs 공통:

    • 공통: 드라이버/연결/해제
    • 변함: SQL/바인딩
  3. 반복:

    • 공통 부분 매번

3️⃣ 한 메서드의 5가지 관심사

3.1 5가지 관심사

한 메서드의 관심사:

1. DB 연결 정보 관리
   - URL, 계정, 비밀번호

2. DB 드라이버 로딩
   - Class.forName

3. SQL 작성과 실행
   - PreparedStatement

4. 파라미터 바인딩
   - setXxx

5. 자원 해제
   - close

3.2 관심사란

관심사 (Concern):

  코드가 다루는 하나의 주제·책임.
  - 변경의 이유
  - SRP 와 직결

  여러 관심사 한 곳 = 문제

3.3 관심사별 변경 이유

관심사별 변경 이유:

연결 정보: DB 서버 변경
드라이버: DB 종류 변경
SQL: 쿼리 변경
바인딩: 컬럼 변경
자원 해제: (보통 불변)

→ 각자 다른 이유로 변경

3.4 한 곳에 모인 문제

한 곳에 모인 문제:

  여러 관심사 한 메서드:
    - 한 이유로 변경해도
    - 다른 관심사 코드 건드림
    - 영향 범위 넓음

  → SRP 위반

3.5 ILIC 의 맥락

public class ShipmentDao {
    
    public void add(Shipment shipment) throws Exception {
        // [관심사 1] DB 드라이버 로딩
        Class.forName("com.mysql.jdbc.Driver");
        
        // [관심사 2] DB 연결 정보 (URL, 계정, 비밀번호)
        Connection c = DriverManager.getConnection(
            "jdbc:mysql://localhost/ilic", "root", "password");
        
        // [관심사 3] SQL 작성
        PreparedStatement ps = c.prepareStatement(
            "insert into shipments(id, bl_no, weight) values(?, ?, ?)");
        
        // [관심사 4] 파라미터 바인딩
        ps.setLong(1, shipment.getId());
        ps.setString(2, shipment.getBlNo());
        ps.setBigDecimal(3, shipment.getWeight());
        
        ps.executeUpdate();   // [관심사 3] 실행
        
        // [관심사 5] 자원 해제
        ps.close();
        c.close();
    }
    // 5가지 관심사가 한 메서드에
    // → 분리 필요 (다음 Phase)
}

3.6 자기 점검 답변

한 메서드가 신경 쓰는 관심사 5개는?

:
1. 5가지:

  • 연결 정보
  • 드라이버 로딩
  • SQL 작성/실행
  • 파라미터 바인딩
  • 자원 해제
  1. 관심사:

    • 변경의 이유
  2. 변경 이유:

    • 각자 다름
  3. 문제:

    • 한 곳에 모임 (SRP 위반)

4️⃣ DB 종류 변경 시

4.1 MySQL → Oracle

DB 종류 변경 (MySQL → Oracle):

  수정해야 할 것:
    - 드라이버: com.mysql → oracle.jdbc
    - URL: jdbc:mysql → jdbc:oracle
    - (일부 SQL 문법)

  모든 메서드에 박혀 있음

4.2 수정 범위

수정 범위:

  드라이버/URL 이:
    - add 에 박힘
    - get 에 박힘
    - update 에 박힘
    - delete 에 박힘
    - ...

  → 모든 메서드 수정

4.3 코드

// MySQL 버전
Class.forName("com.mysql.jdbc.Driver");
Connection c = DriverManager.getConnection(
    "jdbc:mysql://localhost/ilic", ...);

// Oracle 로 변경 → 모든 메서드 수정
Class.forName("oracle.jdbc.OracleDriver");
Connection c = DriverManager.getConnection(
    "jdbc:oracle:thin:@localhost:1521:ilic", ...);

// add, get, update, delete ... 전부 수정

4.4 변경 비용

변경 비용:

  메서드 N개:
    - N곳 수정
    - 실수 가능
    - 누락 위험

  → "변경 1번 = 수정 N곳"

4.5 ILIC 의 맥락

// ❌ DB 변경이 모든 메서드에 영향
public class ShipmentDao {
    
    public void add(Shipment s) throws Exception {
        Class.forName("com.mysql.jdbc.Driver");   // 수정 대상
        Connection c = DriverManager.getConnection(
            "jdbc:mysql://localhost/ilic", "root", "password");   // 수정 대상
        // ...
    }
    
    public Shipment get(Long id) throws Exception {
        Class.forName("com.mysql.jdbc.Driver");   // 또 수정
        Connection c = DriverManager.getConnection(
            "jdbc:mysql://localhost/ilic", "root", "password");   // 또 수정
        // ...
        return null;
    }
    
    public void update(Shipment s) throws Exception {
        Class.forName("com.mysql.jdbc.Driver");   // 또또 수정
        // ...
    }
    // MySQL → Oracle: 모든 메서드 수정 (유지보수 지옥)
}

4.6 자기 점검 답변

DB 종류 변경 시 수정 범위는?

:
1. 변경 대상:

  • 드라이버, URL
  1. 범위:

    • 모든 메서드
  2. 이유:

    • 메서드마다 박힘
  3. 비용:

    • 변경 1번 = N곳

5️⃣ 접속 정보 변경 시

5.1 접속 정보

접속 정보:

  - URL
  - 계정 (user)
  - 비밀번호 (password)

  메서드마다 하드코딩

5.2 변경 시나리오

변경 시나리오:

  - 비밀번호 변경 (보안 정책)
  - DB 서버 이전 (URL)
  - 계정 변경

  → 모든 메서드 수정

5.3 하드코딩 문제

// 하드코딩 (문제)
Connection c = DriverManager.getConnection(
    "jdbc:mysql://localhost/ilic",   // URL 하드코딩
    "root",                           // 계정 하드코딩
    "password");                      // 비밀번호 하드코딩!

// 비밀번호 변경:
// - 모든 메서드 수정
// - 보안 위험 (코드에 노출)

5.4 보안 문제

보안 문제:

  비밀번호 하드코딩:
    - 소스 코드에 노출
    - 버전 관리에 포함
    - 보안 취약

→ 외부 설정 분리 필요

5.5 ILIC 의 맥락

// ❌ 접속 정보 하드코딩 (모든 메서드)
public class ShipmentDao {
    public void add(Shipment s) throws Exception {
        Connection c = DriverManager.getConnection(
            "jdbc:mysql://localhost/ilic", "root", "password");  // 하드코딩
    }
    public Shipment get(Long id) throws Exception {
        Connection c = DriverManager.getConnection(
            "jdbc:mysql://localhost/ilic", "root", "password");  // 또 하드코딩
        return null;
    }
}

// 비밀번호 변경 → 모든 메서드 수정 + 보안 위험
// 해결 방향:
// - 연결 생성 분리 (다음 Phase)
// - 외부 설정 (application.yml)

5.6 자기 점검 답변

접속 정보 변경 시 수정 범위는?

:
1. 접속 정보:

  • URL, 계정, 비밀번호
  1. 변경 시나리오:

    • 비밀번호, 서버 이전
  2. 하드코딩 문제:

    • 모든 메서드 수정
  3. 보안:

    • 코드 노출
    • 외부 설정 필요

6️⃣ 메서드 간 중복

6.1 중복 코드

메서드 간 중복:

  공통 코드 반복:
    - 드라이버 로딩
    - 연결 생성
    - 자원 해제

  add, get, update, delete ... 모두

6.2 중복의 문제

중복의 문제:

  - 변경 시 모두 수정
  - 실수/누락 위험
  - 코드 비대
  - DRY 위반

6.3 DRY 원칙

DRY (Don't Repeat Yourself):

  중복을 제거하라:
    - 한 곳에서 관리
    - 변경 한 곳
    - 일관성

  중복 = 유지보수 부담

6.4 중복 예시

// 중복 (getConnection 부분)
public void add(...) {
    Class.forName("com.mysql.jdbc.Driver");      // 중복
    Connection c = DriverManager.getConnection(...);  // 중복
    // ...
}
public User get(...) {
    Class.forName("com.mysql.jdbc.Driver");      // 중복
    Connection c = DriverManager.getConnection(...);  // 중복
    // ...
}
// 같은 코드 반복
// → 메서드 추출로 해결 (Phase 4)

6.5 ILIC 의 맥락

public class ShipmentDao {
    
    // 중복되는 연결 코드
    public void add(Shipment s) throws Exception {
        Class.forName("com.mysql.jdbc.Driver");   // ↓ 중복
        Connection c = DriverManager.getConnection(
            "jdbc:mysql://localhost/ilic", "root", "password");
        // ...
    }
    
    public Shipment get(Long id) throws Exception {
        Class.forName("com.mysql.jdbc.Driver");   // ↓ 동일 중복
        Connection c = DriverManager.getConnection(
            "jdbc:mysql://localhost/ilic", "root", "password");
        // ...
        return null;
    }
    
    public List<Shipment> findAll() throws Exception {
        Class.forName("com.mysql.jdbc.Driver");   // ↓ 또 중복
        Connection c = DriverManager.getConnection(
            "jdbc:mysql://localhost/ilic", "root", "password");
        // ...
        return List.of();
    }
    // 연결 코드가 3번 중복
    // → getConnection() 메서드 추출 (Phase 4.2)
}

6.6 자기 점검 답변

메서드 간 중복 코드는?

:
1. 중복:

  • 드라이버/연결/해제
  • 메서드마다
  1. 문제:

    • 변경 시 모두 수정
    • DRY 위반
  2. DRY:

    • 반복 제거
  3. 해결:

    • 메서드 추출 (Phase 4)

7️⃣ 자원 해제

7.1 자원 해제 중요성

자원 해제 중요성:

  Connection, Statement, ResultSet:
    - 사용 후 반드시 close
    - 안 하면 자원 누수

  → 연결 고갈, 메모리 누수

7.2 누수의 위험

자원 누수 위험:

  close 안 하면:
    - 연결 풀 고갈
    - "Too many connections"
    - 메모리 누수
    - 서버 다운

→ 반드시 해제

7.3 finally 해제

// finally 로 자원 해제 (전통)
Connection c = null;
PreparedStatement ps = null;
try {
    c = getConnection();
    ps = c.prepareStatement(sql);
    ps.executeUpdate();
} catch (SQLException e) {
    // 예외 처리
} finally {
    // 반드시 해제
    if (ps != null) try { ps.close(); } catch (SQLException e) {}
    if (c != null) try { c.close(); } catch (SQLException e) {}
}
// 복잡하고 장황

7.4 try-with-resources

// try-with-resources (Java 7+, 개선)
try (Connection c = getConnection();
     PreparedStatement ps = c.prepareStatement(sql)) {
    ps.executeUpdate();
}   // 자동 close (AutoCloseable)
// 훨씬 간결

7.5 ILIC 의 맥락

public class ShipmentDao {
    
    // ❌ 자원 해제 누락 (위험)
    public void addUnsafe(Shipment s) throws Exception {
        Connection c = getConnection();
        PreparedStatement ps = c.prepareStatement("insert ...");
        ps.executeUpdate();
        // 예외 발생 시 close 안 됨 → 누수!
        ps.close();
        c.close();
    }
    
    // ✓ try-with-resources (안전)
    public void addSafe(Shipment s) throws Exception {
        String sql = "insert into shipments(id, bl_no, weight) values(?, ?, ?)";
        try (Connection c = getConnection();
             PreparedStatement ps = c.prepareStatement(sql)) {
            ps.setLong(1, s.getId());
            ps.setString(2, s.getBlNo());
            ps.setBigDecimal(3, s.getWeight());
            ps.executeUpdate();
        }   // 자동 해제 (예외에도)
    }
    
    private Connection getConnection() throws Exception {
        return DriverManager.getConnection(
            "jdbc:mysql://localhost/ilic", "root", "password");
    }
}

7.6 자기 점검 답변

자원 해제의 중요성은?

:
1. 중요성:

  • 반드시 close
  • 자원 누수 방지
  1. 누수 위험:

    • 연결 고갈
    • 서버 다운
  2. finally:

    • 전통 (장황)
  3. try-with-resources:

    • 자동 (간결)

8️⃣ 예외 처리

8.1 checked 예외

JDBC checked 예외:

  - ClassNotFoundException (드라이버)
  - SQLException (DB 작업)

  → throws 또는 try-catch 강제

8.2 예외 전파

// 예외 throws (전파)
public void add(Shipment s) 
        throws ClassNotFoundException, SQLException {
    // checked 예외 던짐
    // 호출자가 처리해야
}

// 호출하는 비즈니스 코드:
try {
    dao.add(shipment);
} catch (ClassNotFoundException | SQLException e) {
    // 비즈니스 코드에 기술 예외 노출 (문제)
}

8.3 기술 예외 노출

기술 예외 노출 문제:

  SQLException 이:
    - 비즈니스 코드에 전파
    - 기술 세부사항 노출
    - 비즈니스가 DB 예외 처리

  → 추상화 누수

8.4 unchecked 변환

// unchecked 로 변환 (개선)
public void add(Shipment s) {
    try {
        // JDBC 작업
    } catch (SQLException e) {
        throw new RuntimeException("DB 오류", e);   // unchecked
    }
}
// Spring: DataAccessException (unchecked)
// 비즈니스가 기술 예외 안 봄

8.5 ILIC 의 맥락

public class ShipmentDao {
    
    // ❌ checked 예외 전파 (비즈니스에 부담)
    public void addChecked(Shipment s) 
            throws ClassNotFoundException, SQLException {
        // 호출자가 기술 예외 처리해야
    }
    
    // ✓ unchecked 변환 (추상화)
    public void addUnchecked(Shipment shipment) {
        String sql = "insert into shipments(id, bl_no, weight) values(?, ?, ?)";
        try (Connection c = getConnection();
             PreparedStatement ps = c.prepareStatement(sql)) {
            ps.setLong(1, shipment.getId());
            ps.setString(2, shipment.getBlNo());
            ps.setBigDecimal(3, shipment.getWeight());
            ps.executeUpdate();
        } catch (SQLException e) {
            throw new DataAccessException("배송 저장 실패", e);   // unchecked
        }
    }
    
    private Connection getConnection() throws SQLException {
        return DriverManager.getConnection(
            "jdbc:mysql://localhost/ilic", "root", "password");
    }
    
    static class DataAccessException extends RuntimeException {
        DataAccessException(String msg, Throwable cause) { super(msg, cause); }
    }
}

8.6 자기 점검 답변

예외 처리의 복잡성은?

:
1. checked:

  • ClassNotFoundException
  • SQLException
  1. 전파:

    • throws (호출자 처리)
  2. 기술 예외 노출:

    • 비즈니스에 DB 예외
  3. 개선:

    • unchecked 변환
    • DataAccessException

9️⃣ 면접 + 자기 점검

9.1 면접 단골 질문 매핑

Q핵심 답변
전통 DAO 단계?드라이버~자원해제 6단계
6단계?로딩/연결/SQL/바인딩/실행/해제
관심사 5개?연결정보/드라이버/SQL/바인딩/해제
DB 변경?모든 메서드 수정
접속 정보?하드코딩, 보안 위험
중복?연결 코드 반복
자원 해제?누수 방지 (try-with-resources)
예외?checked, unchecked 변환
문제 출발점?모든 책임 한 곳

9.2 자기 점검 체크리스트

6단계

  • 드라이버~해제

관심사 5개

  • 연결/드라이버/SQL/바인딩/해제

DB 변경

  • 모든 메서드

접속 정보

  • 하드코딩

중복

  • 연결 코드

자원 해제

  • try-with-resources

예외

  • unchecked 변환

9.3 추가 심화 질문

Q1: Class.forName 이 필요 없어진 이유?

답:

  • JDBC 4.0+ (Java 6)
  • 자동 드라이버 로딩 (SPI)
  • META-INF/services
  • 명시적 로딩 불필요

Q2: Connection Pool?

답:

  • 연결 재사용 (DAO 와 유사 개념)
  • HikariCP, DBCP
  • 매번 연결 생성 X
  • 성능 ↑

Q3: PreparedStatement vs Statement?

답:

  • PreparedStatement: 파라미터 바인딩 (SQL 인젝션 방지)
  • Statement: 문자열 직접 (위험)
  • 항상 PreparedStatement
  • 캐싱 이점

Q4: ResultSet 매핑 자동화?

답:

  • RowMapper (Spring)
  • ORM (JPA)
  • 수동 매핑 제거
  • 반복 줄임

Q5: 전통 DAO 의 SRP 위반?

답:

  • 5가지 관심사 한 메서드
  • 단일 책임 위반
  • 변경 이유 여럿
  • 분리 필요 (Phase 4)

🎯 핵심 요약 — 3줄 정리

1. 전통 DAO 코드

  • 한 메서드에 6단계 (드라이버~자원해제)
  • 5가지 관심사 혼재

2. 변경의 고통

  • DB 종류 변경 → 모든 메서드 수정
  • 접속 정보 변경 → 모든 메서드 수정
  • 연결 코드 중복 (DRY 위반)

3. 문제의 출발점

  • 모든 책임 한 곳 (SRP 위반)
  • → 다음 Phase 에서 리팩토링

📚 다음으로...

Unit 3.3 — 무엇이 문제인가 (책임 혼재)

이번 Unit에서 전통 DAO 코드를 봤다면, 다음은 책임 혼재 진단 (Phase 3 마지막).

  • 한 메서드의 책임 분석
  • 변경 1번 = 수정 N곳
  • SOLID 원칙 위반

Phase 3 진행 상황

🌱 Phase 3 — 전통 DAO의 문제
  ✅ Unit 3.1 DAO란 무엇인가
  ✅ Unit 3.2 전통 DAO의 코드 ← 여기
  ⏭ Unit 3.3 책임 혼재

5주차 누적 진행

✅ Part A — 동시성 마무리 (7 Unit)
🌱 Part B — 토비의 스프링
  Phase 3 — 전통 DAO (2/3 진행)

총: 9/26 Unit
profile
Software Developer

0개의 댓글