본문 바로가기
개발

스프링과 SOLID 원칙

by PilYeooong 2024. 5. 21.

SOLID 란?

컴퓨터 프로그래밍에서 SOLID란 로버트 마틴이 2000년대 초반에 명명한 객체 지향 프로그래밍 및 설계의 다섯 가지 기본 원칙을 의미한다.

  1. SRP (Single Responsibility Principle) - 단일 책임 원칙
  2. OCP (Open/Closed Principle) - 개방/폐쇄 원칙
  3. LSP (Liskov Substitution Principle) - 리스코프 치환 원칙
  4. ISP (Interface Segregation Principle) - 인터페이스 분리 원칙
  5. DIP (Dependency Inversion Principle) - 의존성 역전 원칙

이 다섯가지 원칙이 스프링에 어떻게 적용되는지 정리해본다.

 


 

1. 단일 책임 원칙 (SRP)

  • 정의
    • 클래스는 하나의 책임만 가져야 한다.
  • 스프링 적용
    • 스프링은 애플리케이션의 구성 요소를 작은 서비스, 컨트롤러, 리포지토리 등으로 분리하여 SRP를 자연스럽게 준수하도록 돕는다.
      • 구성 영역 (AppConfig, ApplicationContext…) + 실행 영역 (Service, Repository …)
    • 구현 객체를 생성하고, 연결 및 의존성을 주입해주는 책임은 구성 영역에서 담당한다.
    • 실행 영역에서는 오로지 로직을 실행하는 책임만을 담당한다.

 

2. 개방/폐쇄 원칙 (OCP)

  • 정의
    • 소프트웨어 요소는 확장에는 열려 있어야 하지만 변경에는 닫혀 있어야 한다.
  • 스프링 적용
    • 의존성 주입과 빈 설정을 통해 새로운 기능 추가를 쉽게 하면서도 기존 코드를 변경하지 않도록 돕는다.
    • 소프트웨어 요소를 새롭게 확장해도 실행 영역의 변경은 이루어지지 않아도 된다. 구성 영역에서만 의존 관계를 재정의함으로써 해당 원칙을 지킬 수 있다.

 

3. 리스코프 치환 원칙 (LSP)

  • 정의
    • 프로그램의 객체는 프로그램의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 한다.
      • 여기서 특정 인터페이스 기반으로 구현된 클래스의 인스턴스를 하위 타입 인스턴스라 칭한다.
    • 하위 타입의 인스턴스로 치환하더라도 프로그램의 동작이 바뀌지 않아야 한다
  • 스프링 적용
    • 인터페이스와 다형성을 활용하여, 특정 타입의 빈이 필요한 곳에서는 그 인터페이스를 구현하는 어떤 클래스의 인스턴스라도 사용할 수 있다.
    • 이를 통해 클라이언트 코드가 특정 구현체에 의존하지 않도록 설계한다.

 

4. 인터페이스 분리 원칙 (ISP)

  • 정의
    • 클라이언트가 자신이 이용하지 않는 메서드에 의존하지 않아야 한다는 원칙
  • 스프링 적용
    • 역할에 따라 인터페이스를 분리하여, 클라이언트가 자신이 필요로 하는 기능만을 제공하는 인터페이스에 의존하도록 한다.
    • 큰 덩어리의 인터페이스들을 구체적이고 작은 단위로 분리 시킴으로써 클라이언트들이 꼭 필요한 메서드만 이용할 수 있도록 한다.

 

5. 의존성 역전 원칙 (DIP)

  • 정의
    • 상위와 하위 객체 모두 추상화에 의존해야 한다.
  • 스프링 적용
    • 추상화에 의존해야하며, 구체화에 의존하지 않는다. 의존성 주입은 이 원칙을 따르는 방법 중 하나이다.
      • 즉, 클라이언트는 인터페이스만 의존하면 된다. 구현체에 의존하지 않는다.
      • 새로운 기능이 추가되더라도 인터페이스를 의존하기 때문에 클라이언트 코드 변경이 필요하지 않다.
    • 구현체는 스프링 컨테이너가 주입하여 준다.
      • @Autowired, @Inject, @Resource 어노테이션 등을 사용하여 의존성 주입을 자동으로 처리한다.
    • 실행 영역에서는 인터페이스만 의존하고 있다.
      • 실행 영역에서는 어떤 구현체가 주입되어있는지 모르며 오로지 실행만을 담당한다.
      • 구현체가 변경되더라도 실행 영역에서의 코드 변경은 필요하지 않다. ApplicationContext에서 새로 정의된 구현체를 주입해주기만하면 된다.

'개발' 카테고리의 다른 글

비행기표 조회 자동화  (0) 2024.08.09
RDB에서 인덱스를 사용하지 않는 케이스들  (0) 2024.05.31
스프링과 싱글턴  (0) 2024.05.26
Kotlin 간단 정리  (0) 2024.04.16