10/29

졸용·2025년 10월 29일

TIL

목록 보기
103/144

🔹 DIP란?

DIP(Dependency Inversion Principle, 의존성 역전 원칙)은 SOLID 원칙의 다섯 번째 원칙으로,

“상위 모듈이 하위 모듈에 의존하지 않고, 둘 다 추상화(인터페이스)에 의존해야 한다”는 개념을 말한다.


🔸 정의

  • "고수준 모듈은 저수준 모듈에 의존해서는 안 된다. 둘 다 추상화에 의존해야 한다."
  • "추상화는 세부사항에 의존해서는 안 된다. 세부사항이 추상화에 의존해야 한다."

즉, 의존 방향을 구체적인 클래스에서 추상적인 인터페이스로 ‘역전’시키는 것이 핵심이다.



🔹 예시

❌ DIP 위반 예시

class MySQLRepository {
    public void save(String data) {
        System.out.println("Save to MySQL: " + data);
    }
}

class UserService {
    private final MySQLRepository repository = new MySQLRepository(); // 직접 의존 ❌

    public void register(String user) {
        repository.save(user);
    }
}
  • UserService(상위 모듈)가 MySQLRepository(하위 모듈)에 직접 의존.
  • 만약 PostgreSQLRepository로 바꾸면 UserService 코드도 수정해야 함 → OCP, DIP 모두 위반.

✅ DIP 적용 예시

interface UserRepository {
    void save(String data);
}

class MySQLRepository implements UserRepository {
    public void save(String data) {
        System.out.println("Save to MySQL: " + data);
    }
}

class PostgreSQLRepository implements UserRepository {
    public void save(String data) {
        System.out.println("Save to PostgreSQL: " + data);
    }
}

class UserService {
    private final UserRepository repository; // 인터페이스에 의존 ✅

    public UserService(UserRepository repository) {
        this.repository = repository;
    }

    public void register(String user) {
        repository.save(user);
    }
}
  • UserService는 더 이상 구체적인 DB에 관심이 없고,
    UserRepository라는 추상화(인터페이스)에만 의존한다.


🔹 DIP가 필요한 이유

구분DIP 미적용DIP 적용
의존 관계구체 클래스에 의존추상 인터페이스에 의존
변경 시 영향상위 모듈 수정 필요하위 모듈만 수정
확장성낮음높음
테스트 용이성어려움 (실 DB 필요)쉬움 (Mock 구현 주입 가능)


🔹 DIP와 스프링의 관계

Spring Framework는 DIP를 실현하기 위한 대표적인 프레임워크다.
그 핵심이 바로 DI(Dependency Injection, 의존성 주입)이다.

@Service
public class UserService {
    private final UserRepository userRepository;

    // 생성자 주입으로 인터페이스를 받음
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
}
  • UserServiceUserRepository 인터페이스만 알고 있고,
  • 구체 클래스(MySQL, JPA, Redis 등)는 Spring Container가 런타임에 주입.
  • → 코드 수정 없이 구현체를 바꿀 수 있음 (유연하고 확장 가능한 구조)


🔹 실제 적용 사례 예시: Spring의 Repository 구조

  • JpaRepository는 인터페이스(추상화)
  • SimpleJpaRepository는 구현체(세부사항)
  • 개발자는 JpaRepository에 의존 → DIP 준수
public interface UserRepository extends JpaRepository<User, UUID> {
}

실제 구현체는 Spring Data JPA가 런타임에 주입
→ 개발자는 DB 구현체를 몰라도 비즈니스 로직 개발 가능.



🔹 요약

항목설명
이름DIP (Dependency Inversion Principle)
핵심 문장“상위 모듈은 하위 모듈에 의존하지 않는다. 둘 다 추상화에 의존한다.”
목적유연하고 확장 가능한 구조, 테스트 용이성
실현 방법인터페이스 사용 + DI(의존성 주입)
관련 원칙OCP(개방-폐쇄 원칙)과 밀접하게 연관됨
profile
꾸준한 공부만이 답이다

0개의 댓글