토비의 스프링 이해와 원리

Daniel_Yang·2024년 8월 21일
0

공부하기 전 나의 상황

  • 스프링부트에 중독되어 스프링의 동작 원리가 가물가물해졌다.
  • 스프링의 다양한 기술을 사용해보았으나, 여기에 적용된 공통적인 동작 원리까지 생각하진 못했다.

결론

  • 스프링이 개발자에게 무엇을 요구하고 어떤 코드를 기대하는지 알게 되었다.
  • 더 격하게 테스크 코드를 활용하고 싶어졌다.
  • 라이브러리와 프레임워크 사용 시, 문제 제기 > 해결 시도 > 리팩토링 > 라이브러리와 프레임워크가 어떻게 이를 적용하는지 생각!
  • 스프링이 유용한 이유는 여러 설계 원칙, 그리고 디자인 패턴들이 우리가 작성하는 코드에 잘 녹아져서 우리가 만드는 코드의 품질을 높이고 유지보수성을 뛰어나게하고 OCP에 부합하도록 잘 이끄도록 한다.
  • 다른 회사에서 우리 코드를 라이브러리 형태로 가져다쓰고 싶을 것을 가정하여 리팩토링하자.

관심사

  • 여러 관심사가 섞혀있는 코드를 읽으면 보기가 어렵다.
  • 언젠가 변경될 수 있는 가능성을 염두해야한다.

변경되는 시점/이유에 따라 분리하자

  1. 사용하는 방법(기술)이 달라지거나
  2. 비즈니스 룰/로직이 달라지거나

관심사 분리 방법(점진적 개선)

  • 메서드 분리
  • 상속을 통한 확장 ex) abstract
    - 만약 로직이 추가된다면?
  • 클래스 분리
    - 클래스마다 제공하는 메서드명이 달라질 수 있다.
  • 인터페이스 도입(메서드명 통일)
    - 여전히 클래스 생성시, 코드 수정해야하는 문제
  • 관계설정 책임의 분리
    - 생성자 주입을 통해 결합 느슨하게
    • 제어권 이전: 관계설정 책임을 다른 곳에서 진행 ex) 클라이언트
    • 허나, 클라이언트가 메인 메서드와 관계설정 두가지 관심사 갖고있다.
  • 오브젝트 팩토리 : 스프링의 핵심

오브젝트와 의존관계

  • 스프링이 다루는 것 중 제일 관심있는 것은 오브젝트며, 우리를 가장 많이 도와주는 것은 의존관계이다.
  • 오브젝트 사이에서 대신 해달라는 의존관계들이 런타임에서 발생한다.

스프링 컨테이너와 의존관계 주입

  • 스프링 컨테이너
    • 가장 핵심, 가장 중요하고 모든 것에 기반이 되는 스프링의 기능
    • 특징: IoC, DI 를 제공
    • 구성정보(Configuration MetaData)을 통해 생성 ex) config, @Component, @ComponentScan
    • BeanFactory: Bean을 한번 생성해서 리턴해주고 끝나는게 아니라 얘를 계속 담아두는 컨테이너이기도 하다. = IoC 컨테이너, 스프링 컨테이너, 스프링
      => 싱글톤이 쉽다.

기타

OCP: 개방 폐쇄 원칙

  • 클래스나 모듈은 확장에는 열려 있어야하고 변경에는 닫혀있어야한다.
    어떤 클래스는 이 클래스의 기능을 확장할 때 그 클래스의 코드는 변경되면 안 된다.

전략 패턴

  • 자신의 기능 맥락(context)에서, 필요에 따라서 변경이 필요한 알고리즘을 인터페이스를 통해 통째로 외부로 분리시키고, 이를 구현한 구체적인 알고리즘 클래스를 필요에 따라 바꿔서 사용할 수 있게 하는 디자인 패턴

데코레이터 패턴

  • 구성정보만 바뀌었지, 기존 코드는 변경점이 없도록
  • A--->B 의존 시, 새로운 로직이 필요하다면 A나 B 변경 없이 A--->C--->B 처럼 C를 통해 A는 B의 메서드 그대로 사용가능하고, C는 B의 메서드에 로직 추가 등 진행할 수 있다.
  • DIP 원칙을 실현하는 방법 중 하나

의존성 역전 원칙(DIP)

  • 기존 구조는 아래 모듈에서 변경이 일어날 때 상위 모듈에서 변경이 필요해진다.
  • 고수준 모듈: 중요한 정책을 정의하거나 비즈니스 로직을 담당하는 모듈.
  • 저수준 모듈: 실제로 작업을 수행하는 구현 세부 사항을 가진 모듈.
  • 목표: DIP는 시스템의 유연성과 확장성을 높이기 위해, 고수준 모듈이 저수준 모듈에 직접 의존하지 않고, 추상화된 인터페이스를 통해 의존성을 주입받도록 설계합니다.
  • 인터페이스를 이를 구현한 클래스 쪽 모듈에 두는 것이 아니라 사용하는 클라이언트 쪽에 역전한다.(인터페이스 소유권의 이전)

0개의 댓글