5주차 Unit 4.1 — 관심사의 분리 개념

Psj·2026년 5월 27일

F-lab

목록 보기
166/240

Unit 4.1 — 관심사의 분리 개념

F-LAB JAVA · 5주차 · Phase 4 · 관심사의 분리
🌱 Phase 4 시작 — ★ 깊이 파기 (Spring 이해의 출발점)


📌 학습 목표

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

  • 관심사의 분리 (Separation of Concerns) 원칙은?
  • 관심사 (Concern) 의 의미 는?
  • "관심이 같은 것끼리 모으고 다른 것은 떨어뜨려라" 의 뜻은?
  • 관심사와 책임 (Responsibility) 의 관계 는?
  • 변경의 이유와 관심사 의 연결은?
  • DAO 에서 분리해야 할 첫 번째 관심사 는?
  • 처음엔 한데 모은 게 편한데 분리하는 이유는?
  • 관심사 분리의 효과 는?
  • SRP 와 관심사 분리 의 관계는?

🎯 핵심 한 문장

관심사의 분리 (Separation of Concerns) 는 "관심이 같은 것끼리는 하나로 모으고, 관심이 다른 것은 떨어뜨려라" 는 리팩토링의 가장 기본 원리로, 여기서 관심사 (Concern) 는 코드가 다루는 하나의 주제·책임이며 변경의 이유와 일치한다.
관심사 는 코드가 신경 쓰는 하나의 주제로, 전통 DAO 에서는 "DB 연결", "SQL 실행", "예외 처리" 등이 각각의 관심사다.
"같은 것끼리 모으고 다른 것은 떨어뜨려라" 는 같은 관심사 (예: 모든 연결 생성 코드) 는 한 곳에 모아 관리하고, 다른 관심사 (연결과 SQL) 는 분리하라는 뜻이다.
관심사는 변경의 이유와 일치 하므로 (DB 변경 시 연결 관심사만, 스키마 변경 시 SQL 관심사만 바뀜), 관심사 분리는 곧 SRP (단일 책임 원칙) 와 직결된다.
처음엔 모든 코드를 한 메서드에 모으는 게 편하지만, 시스템이 커지면 분리하지 않으면 변경이 어려워져 살아남을 수 없으므로, DAO 에서 가장 먼저 분리할 관심사는 반복되는 DB 연결 생성 이다.

비유 — 주방 정리

관심사의 분리 = 주방 정리:

같은 것끼리 모으기:
  - 칼은 칼꽂이에
  - 양념은 양념통에
  - 그릇은 그릇장에

다른 것은 떨어뜨리기:
  - 칼과 양념 섞지 않기
  - 각자 자리

처음엔 (분리 X):
  - 다 한 서랍에 (편함)
  - 작을 땐 OK

커지면 (분리 필요):
  - 뭐가 어디 있는지 모름
  - 칼 찾다 베임
  - 정리해야 살아남음

관심사 = 주방 도구의 종류:
  - 자르는 도구 (관심사 1)
  - 양념 (관심사 2)
  - 변경 이유 다름

→ 관심사의 분리 = 같은 것 모으고 다른 것 분리, 관심사 = 변경의 이유.


🧭 9개 섹션 로드맵

1. 관심사의 분리 원칙
2. 관심사(Concern)의 의미
3. 모으고 떨어뜨리기
4. 관심사와 책임
5. 변경의 이유와 관심사
6. DAO의 첫 관심사
7. 왜 분리하는가
8. SRP와의 관계
9. 면접 + 자기 점검

1️⃣ 관심사의 분리 원칙

1.1 원칙

관심사의 분리 (Separation of Concerns):

  "관심이 같은 것끼리는 하나로 모으고,
   관심이 다른 것은 떨어뜨려라"

  리팩토링의 가장 기본 원리

1.2 핵심 아이디어

핵심 아이디어:

  코드를 관심사 단위로:
    - 같은 관심사 → 모음
    - 다른 관심사 → 분리

  → 각 관심사 독립 관리

1.3 전통 DAO 의 문제 재확인

전통 DAO 문제 (관심사 관점):

  한 메서드에:
    - 연결 관심사
    - SQL 관심사
    - 예외 관심사

  여러 관심사 섞임
  → 분리 필요

1.4 분리의 방향

분리 방향:

  1단계: 메서드 추출 (같은 관심사 모음)
  2단계: 클래스 분리 (다른 관심사 분리)
  3단계: 인터페이스 (추상화)

  → 점진적 분리

1.5 ILIC 의 맥락

// 관심사 분리 전 (혼재)
public class ShipmentDaoBefore {
    public void add(Shipment s) throws Exception {
        // [연결 관심사] + [SQL 관심사] 혼재
        Class.forName("com.mysql.jdbc.Driver");
        Connection c = DriverManager.getConnection(...);
        PreparedStatement ps = c.prepareStatement("insert ...");
        ps.executeUpdate();
        ps.close(); c.close();
    }
}

// 관심사 분리 후 (방향)
public class ShipmentDaoAfter {
    // [SQL 관심사] 만 남김
    public void add(Shipment s) throws Exception {
        Connection c = getConnection();   // [연결 관심사] 분리
        PreparedStatement ps = c.prepareStatement("insert ...");
        ps.executeUpdate();
        ps.close(); c.close();
    }
    
    // [연결 관심사] 한 곳에 모음
    private Connection getConnection() throws Exception {
        Class.forName("com.mysql.jdbc.Driver");
        return DriverManager.getConnection(...);
    }
}

1.6 자기 점검 답변

관심사의 분리 원칙은?

:
1. 원칙:

  • 같은 것 모음
  • 다른 것 분리
  1. 아이디어:

    • 관심사 단위
  2. DAO 문제:

    • 여러 관심사 섞임
  3. 방향:

    • 메서드 → 클래스 → 인터페이스

2️⃣ 관심사(Concern)의 의미

2.1 관심사

관심사 (Concern):

  코드가 다루는 하나의 주제·책임.
  - 코드가 신경 쓰는 것
  - 변경의 이유

2.2 예시

관심사 예시 (DAO):

  - "DB 에 어떻게 연결하나" (연결)
  - "어떤 SQL 을 실행하나" (SQL)
  - "예외를 어떻게 처리하나" (예외)
  - "자원을 어떻게 해제하나" (해제)

  각각이 관심사

2.3 관심사 식별

관심사 식별:

  "이 코드가 다루는 주제는?"
    - 연결 생성 → 연결 관심사
    - 쿼리 실행 → SQL 관심사

  "이 코드가 바뀌는 이유는?"
    - DB 변경 → 연결 관심사

2.4 관심사 크기

관심사 크기:

  너무 작으면:
    - 과도한 분리
    - 복잡

  너무 크면:
    - 여러 책임
    - 혼재

  → 적절한 단위

2.5 ILIC 의 맥락

// ILIC DAO 의 관심사들
public class ShipmentDao {
    public void add(Shipment s) throws Exception {
        // 관심사 1: DB 연결 (어떻게 연결?)
        Class.forName("com.mysql.jdbc.Driver");
        Connection c = DriverManager.getConnection(...);
        
        // 관심사 2: SQL 실행 (무엇을 저장?)
        PreparedStatement ps = c.prepareStatement(
            "insert into shipments(id, bl_no, weight) values(?, ?, ?)");
        ps.setLong(1, s.getId());
        ps.executeUpdate();
        
        // 관심사 3: 자원 해제 (어떻게 정리?)
        ps.close();
        c.close();
        
        // 관심사 4: 예외 처리 (throws)
    }
    // 4가지 관심사 식별 → 분리 대상
}

2.6 자기 점검 답변

관심사(Concern)의 의미는?

:
1. 관심사:

  • 코드가 다루는 주제
  • 변경의 이유
  1. 예시:

    • 연결, SQL, 예외, 해제
  2. 식별:

    • "다루는 주제?"
    • "바뀌는 이유?"
  3. 크기:

    • 적절한 단위

3️⃣ 모으고 떨어뜨리기

3.1 같은 것 모으기

같은 관심사 모으기:

  흩어진 같은 관심사:
    - 메서드마다 연결 코드
    → 한 곳으로 (getConnection)

  → 중복 제거
  → 한 곳 관리

3.2 다른 것 떨어뜨리기

다른 관심사 분리:

  섞인 다른 관심사:
    - 연결 + SQL 한 메서드
    → 분리 (연결은 별도)

  → 각자 독립
  → 변경 격리

3.3 모으기 예시

// 흩어진 연결 코드 (같은 관심사)
public void add(...) {
    Connection c = DriverManager.getConnection(...);  // 여기
}
public void get(...) {
    Connection c = DriverManager.getConnection(...);  // 여기
}

// 모으기 (한 곳)
private Connection getConnection() {
    return DriverManager.getConnection(...);   // 한 곳
}
public void add(...) {
    Connection c = getConnection();   // 사용
}
public void get(...) {
    Connection c = getConnection();   // 사용
}

3.4 떨어뜨리기 예시

// 연결 관심사 분리 (다른 클래스로)
class ConnectionMaker {   // 연결 관심사만
    Connection makeConnection() { ... }
}

class ShipmentDao {       // SQL 관심사만
    private ConnectionMaker connectionMaker;
    // 연결은 ConnectionMaker 에 위임
}
// 두 관심사 떨어뜨림

3.5 ILIC 의 맥락

// 모으기 + 떨어뜨리기

// 1단계: 모으기 (메서드 추출)
public class ShipmentDao {
    private Connection getConnection() throws Exception {
        // 흩어진 연결 코드 모음
        Class.forName("com.mysql.jdbc.Driver");
        return DriverManager.getConnection(
            "jdbc:mysql://localhost/ilic", "root", "password");
    }
    
    public void add(Shipment s) throws Exception {
        Connection c = getConnection();   // 모은 것 사용
        // SQL...
    }
}

// 2단계: 떨어뜨리기 (클래스 분리, Phase 6)
// ConnectionMaker (연결) + ShipmentDao (SQL)

3.6 자기 점검 답변

"관심이 같은 것끼리 모으고 다른 것은 떨어뜨려라" 의 뜻은?

:
1. 같은 것 모으기:

  • 흩어진 연결 → 한 곳
  • 중복 제거
  1. 다른 것 분리:

    • 연결 + SQL → 분리
    • 변경 격리
  2. 모으기:

    • getConnection 추출
  3. 떨어뜨리기:

    • ConnectionMaker 분리

4️⃣ 관심사와 책임

4.1 관계

관심사와 책임:

  거의 같은 의미:
    - 관심사 (Concern)
    - 책임 (Responsibility)

  맥락 차이:
    - 관심사: 코드가 다루는 주제
    - 책임: 클래스/메서드가 해야 할 일

4.2 미묘한 차이

미묘한 차이:

관심사:
  - 더 넓은 개념
  - 횡단 관심사 (cross-cutting)
    예: 로깅, 트랜잭션

책임:
  - 객체/클래스 단위
  - SRP 의 책임

4.3 횡단 관심사

횡단 관심사 (Cross-cutting Concern):

  여러 모듈에 걸친 관심사:
    - 로깅
    - 보안
    - 트랜잭션

  → AOP 로 분리 (나중에)

4.4 실무에서

실무에서:

  관심사 ≈ 책임:
    - 보통 같이 사용
    - "이 코드의 관심사/책임은?"

  → SRP: 하나의 책임
  → SoC: 관심사 분리

4.5 ILIC 의 맥락

// 관심사 = 책임 (보통)
public class ShipmentDao {
    // 책임/관심사: 배송 데이터 접근
    public void add(Shipment s) { }
    public Shipment get(Long id) { return null; }
}

// 횡단 관심사 예시 (AOP)
@Aspect
public class LoggingAspect {
    // 로깅: 여러 클래스에 걸친 횡단 관심사
    @Around("execution(* com.ilic.dao.*.*(..))")
    public Object log(ProceedingJoinPoint pjp) throws Throwable {
        log.info("DAO 호출: {}", pjp.getSignature());
        return pjp.proceed();
        // 모든 DAO 에 로깅 (횡단 관심사 분리)
    }
}

4.6 자기 점검 답변

관심사와 책임(Responsibility)의 관계는?

:
1. 관계:

  • 거의 같은 의미
  1. 차이:

    • 관심사: 넓음 (횡단 포함)
    • 책임: 객체 단위
  2. 횡단 관심사:

    • 로깅, 트랜잭션 (AOP)
  3. 실무:

    • 보통 같이 사용

5️⃣ 변경의 이유와 관심사

5.1 관심사 = 변경 이유

관심사 = 변경의 이유:

  관심사가 다르면:
    - 변경 이유 다름

  연결 관심사:
    - DB 변경 시

  SQL 관심사:
    - 스키마 변경 시

5.2 변경 이유로 분리

변경 이유로 분리:

  "이 코드가 바뀌는 이유는?"
    - 여러 이유 → 여러 관심사
    - 분리

  한 클래스 = 한 변경 이유

5.3 예시

DAO 변경 이유:

  - DB 종류 변경 → 연결 관심사
  - 접속 정보 변경 → 연결 관심사
  - 스키마 변경 → SQL 관심사
  - 비즈니스 규칙 → 서비스

  → 변경 이유별 분리

5.4 격리 효과

격리 효과:

  관심사 분리하면:
    - DB 변경 → 연결 코드만
    - 스키마 변경 → SQL 만
    - 서로 영향 X

  → 변경 격리

5.5 ILIC 의 맥락

// 변경 이유별 분리

// 연결 관심사 (DB 변경 이유)
class ConnectionMaker {
    Connection makeConnection() {
        // DB 종류/접속 정보 변경 → 여기만
        return null;
    }
}

// SQL 관심사 (스키마 변경 이유)
class ShipmentDao {
    private final ConnectionMaker connectionMaker;
    
    public void add(Shipment s) {
        Connection c = connectionMaker.makeConnection();
        // 스키마 변경 → 여기 SQL 만
        // 연결 변경 → 여기 안 건드림 (격리)
    }
}

// 비즈니스 관심사 (규칙 변경 이유)
class ShipmentService {
    private final ShipmentDao dao;
    // 비즈니스 규칙 변경 → 여기만
}

5.6 자기 점검 답변

변경의 이유와 관심사의 연결은?

:
1. 관심사 = 변경 이유:

  • 관심사 다르면 이유 다름
  1. 분리:

    • 변경 이유별
  2. 예시:

    • DB 변경 → 연결
    • 스키마 → SQL
  3. 격리:

    • 변경 영향 차단

6️⃣ DAO의 첫 관심사

6.1 첫 분리 대상

DAO 첫 분리 대상:

  반복되는 DB 연결 생성:
    - 모든 메서드에 중복
    - 가장 명백한 관심사

  → getConnection 분리 (Phase 4.2)

6.2 왜 연결부터

왜 연결부터:

  - 가장 많이 중복
  - 변경 잦음 (DB)
  - 분리 명확
  - 효과 큼

→ 첫 분리로 적합

6.3 연결 관심사

연결 관심사:

  - 드라이버 로딩
  - URL/계정/비밀번호
  - Connection 생성

  → 한 곳으로 (getConnection)

6.4 분리 후 변화

분리 후 변화:

전:
  add, get, update ... 연결 코드 중복

후:
  getConnection (한 곳)
  add, get ... getConnection 사용

→ DB 변경 = getConnection 만

6.5 ILIC 의 맥락

// DAO 첫 관심사 = 연결 생성

// 분리 전 (중복)
public class ShipmentDaoBefore {
    public void add(Shipment s) throws Exception {
        Class.forName("com.mysql.jdbc.Driver");        // 연결 (중복)
        Connection c = DriverManager.getConnection(...);
    }
    public Shipment get(Long id) throws Exception {
        Class.forName("com.mysql.jdbc.Driver");        // 연결 (중복)
        Connection c = DriverManager.getConnection(...);
        return null;
    }
}

// 분리 후 (한 곳)
public class ShipmentDaoAfter {
    // 연결 관심사 한 곳에 모음
    private Connection getConnection() throws Exception {
        Class.forName("com.mysql.jdbc.Driver");
        return DriverManager.getConnection(
            "jdbc:mysql://localhost/ilic", "root", "password");
    }
    
    public void add(Shipment s) throws Exception {
        Connection c = getConnection();   // 사용
    }
    public Shipment get(Long id) throws Exception {
        Connection c = getConnection();   // 사용
        return null;
    }
    // DB 변경 → getConnection 만 수정
}

6.6 자기 점검 답변

DAO에서 분리해야 할 첫 번째 관심사는?

:
1. 첫 대상:

  • DB 연결 생성
  1. :

    • 가장 중복
    • 변경 잦음
  2. 연결 관심사:

    • 드라이버, URL, Connection
  3. 분리 후:

    • getConnection 한 곳

7️⃣ 왜 분리하는가

7.1 처음엔 편함

처음엔 한데 모은 게 편함:

  작은 시스템:
    - 한 곳에 다 (편함)
    - 분리 오버헤드 X
    - 빠른 개발

  초기엔 OK

7.2 커지면 문제

커지면 문제:

  시스템 성장:
    - 코드 비대
    - 변경 어려움
    - 중복 누적
    - 유지보수 ↓

  → 분리 안 하면 살아남기 어려움

7.3 분리의 효과

분리 효과:

1. 변경 용이
   - 관심사별 격리

2. 재사용
   - 분리된 관심사

3. 테스트
   - 독립 테스트

4. 이해
   - 명확한 구조

7.4 트레이드오프

트레이드오프:

  분리:
    + 변경/재사용/테스트
    - 초기 복잡도

  안 분리:
    + 초기 단순
    - 성장 시 부담

→ 시스템 규모에 따라

7.5 ILIC 의 맥락

// ILIC 성장 시나리오

// 초기 (작음) - 한데 모아도 OK
// public void add(Shipment s) { /* 다 한 곳 */ }

// 성장 (102 테이블, 431 API)
// → 분리 필수
public class ShipmentDao {
    private final ConnectionMaker connectionMaker;   // 연결 분리
    private final SqlExecutor sqlExecutor;           // 실행 분리
    
    // 각 관심사 분리 → 102 테이블 관리 가능
    // 분리 안 했으면 → 유지보수 불가
}

interface ConnectionMaker { Connection makeConnection(); }
interface SqlExecutor { void execute(String sql); }

7.6 자기 점검 답변

처음엔 한데 모은 게 편한데 분리하는 이유는?

:
1. 처음엔 편함:

  • 작으면 OK
  1. 커지면 문제:

    • 변경 어려움
    • 살아남기 어려움
  2. 효과:

    • 변경/재사용/테스트
  3. 트레이드오프:

    • 규모에 따라

8️⃣ SRP와의 관계

8.1 SRP

SRP (Single Responsibility Principle):

  "클래스는 단 하나의 책임만"
  - 변경 이유 하나

  = 관심사 분리의 클래스 버전

8.2 SoC vs SRP

SoC vs SRP:

SoC (관심사 분리):
  - 더 넓은 원칙
  - 모든 수준 (시스템/모듈/클래스)

SRP (단일 책임):
  - SoC 의 클래스 적용
  - 하나의 책임

8.3 함께 작동

함께 작동:

  관심사 분리:
    - 관심사별로 나눔

  SRP:
    - 각 클래스 = 하나의 관심사/책임

  → 관심사 분리 = SRP 달성

8.4 적용

적용:

  전통 DAO:
    - 여러 관심사 (SoC 위반)
    - 여러 책임 (SRP 위반)

  분리 후:
    - ConnectionMaker (연결 책임)
    - ShipmentDao (SQL 책임)
    - 각자 SRP

8.5 ILIC 의 맥락

// SoC + SRP 적용

// 연결 관심사 = 연결 책임 (SRP)
interface ConnectionMaker {
    Connection makeConnection();
}
// 변경 이유: DB 연결 방식

// SQL 관심사 = 데이터 접근 책임 (SRP)
class ShipmentDao {
    private final ConnectionMaker connectionMaker;
    public void add(Shipment s) { }
}
// 변경 이유: 배송 데이터 접근

// 비즈니스 관심사 = 비즈니스 책임 (SRP)
class ShipmentService {
    private final ShipmentDao dao;
    public void processBooking(Shipment s) { }
}
// 변경 이유: 비즈니스 규칙

// 각 클래스: 하나의 관심사 = 하나의 책임

8.6 자기 점검 답변

SRP와 관심사 분리의 관계는?

:
1. SRP:

  • 단일 책임 (클래스)
  1. SoC vs SRP:

    • SoC: 넓음
    • SRP: 클래스 적용
  2. 함께:

    • 관심사 분리 = SRP
  3. 적용:

    • 각 클래스 하나의 책임

9️⃣ 면접 + 자기 점검

9.1 면접 단골 질문 매핑

Q핵심 답변
관심사 분리?같은 것 모음, 다른 것 분리
관심사?코드가 다루는 주제 (변경 이유)
모으고 떨어뜨리기?중복 제거, 변경 격리
관심사 vs 책임?거의 같음 (SoC vs SRP)
변경 이유?관심사 = 변경 이유
첫 관심사?DB 연결 생성
왜 분리?성장 시 살아남기
효과?변경/재사용/테스트
SRP 관계?관심사 분리 = SRP
횡단 관심사?로깅/트랜잭션 (AOP)

9.2 자기 점검 체크리스트

관심사 분리

  • 원칙
  • 아이디어

관심사

  • 의미
  • 식별

모으고 떨어뜨리기

  • 중복/격리

관심사 vs 책임

  • 관계

변경 이유

  • 연결

첫 관심사

  • 연결

SRP

  • 관계

9.3 추가 심화 질문

Q1: 횡단 관심사와 AOP?

답:

  • 횡단 관심사: 여러 모듈 걸침 (로깅, 트랜잭션)
  • AOP: 횡단 관심사 분리
  • @Aspect, @Around
  • 비즈니스와 분리

Q2: 관심사 분리의 단점?

답:

  • 과도한 분리: 복잡도 ↑
  • 클래스/인터페이스 증가
  • 추적 어려움 (작은 시스템)
  • 적절한 균형

Q3: 모듈화와 관심사 분리?

답:

  • 모듈화: 시스템 수준 분리
  • 관심사 분리: 코드 수준
  • 같은 정신
  • 다른 스케일

Q4: 관심사 분리와 응집도?

답:

  • 관심사 분리 → 높은 응집
  • 같은 관심사 모음 (응집)
  • 다른 관심사 분리 (결합 ↓)
  • 좋은 설계

Q5: 언제 분리하나?

답:

  • 중복 발견 시
  • 변경 잦은 곳
  • 책임 여럿
  • 너무 이른 분리 X (YAGNI)

🎯 핵심 요약 — 3줄 정리

1. 관심사의 분리

  • 같은 것끼리 모으고, 다른 것은 떨어뜨려라
  • 리팩토링의 가장 기본 원리

2. 관심사 = 변경의 이유

  • 코드가 다루는 주제 (연결, SQL, 예외)
  • 관심사 분리 = SRP 달성

3. DAO 첫 분리

  • 반복되는 DB 연결 생성
  • 처음엔 편하지만 커지면 분리해야 생존

📚 다음으로...

Unit 4.2 — 1단계: 메서드 추출 (getConnection)

이번 Unit에서 관심사 분리 개념을 봤다면, 다음은 메서드 추출 (실제 리팩토링).

  • 중복된 연결 코드 추출
  • getConnection 메서드
  • 얻은 것과 남은 문제

Phase 4 진행 상황

🌱 Phase 4 — 관심사의 분리 (★ 깊이)
  ✅ Unit 4.1 관심사 분리 개념 ← 여기
  ⏭ Unit 4.2 1단계: 메서드 추출
  ⏭ Unit 4.3 2단계: 추상클래스로 확장

5주차 누적 진행

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

총: 11/26 Unit

🌱 Phase 4 시작 — ★ 깊이 파기

profile
Software Developer

0개의 댓글