제어의 역전 IOC(Inversion of Control)

  • 기존프로그램은 클라이언트 구현 객체가 스스로 필요한 서버 구현 객체를 생성하고, 연결하고, 실행했다.
    한마디로 구현 객체가 프로그램의 제어 흐름을 스스로 조종했다. 개발자 입장에서는 자연스러운 흐름이다.
  • 반면에 AppConfig로 설정시 구현객체는 자신의 로직을 실행하는 역할만 담당한다.
    프로그램의 제어 흐름은 이제 AppConfig가 가져간다.
    ex) OrderServiceImpl의 구현객체는 AppConfig에서 정의
  • 프로그램에 대한 흐름에 대한 권한은 모두 AppConfig가 가지고있다.
    이렇듯 프로그램의 제어흐름을 직접제어하는것이 아니라 외부에서 관리하는 것을 제어의 역전(IOC)이라고한다. 

의존관계의 주입 DI(Dependency Injection)

  • OrderServiceImpl은 DiscountPolicy 인터페이스에만 의존한다. 실제 어떤 구현 객체가 사용 될지는 모른다.
  • 의존관계는 정적인 클래스 의존관계와 실행 시점에 결정되는 동적인 객체(인스턴스) 의존관계 둘을 분리해서 생각해야한다.

정적인 클래스 의존관계

  • 클래스에서 사용되는 import되는 코드만 보고 의존관계를 쉽게 판단할 수 있다. 정적인 의존관계는 애플리케이션을 실행하지않아도 분석할 수 있다.
  • 'OrderServiceImpl'은 'MemberRepository'와 'DiscountPolicy'에 의존한다는 것을 알 수 있다.
    하지만, 실제 어떤객체가 주입되었는지는 알 수 없다.

 

동적인 객체 인스턴스 의존관계

  • 애플리케이션 실행 시점에 실제 생성된 객체 인스터스의 참조가 연결된 의존 관계이다.

  • 애플리케이션 실행시점(런타임)에 외부에서 실제 구현 객체를 생성하고, 클라이언트에 전달해서 클라이언트와 서버의 실제 의존관계가 되는 것을 의존관계 주입이라 한다.
  • 객체 인스턴스를 생성하고, 그 참조값을 전달해서 연결된다.
  • 의존관계 주입을 사용하면 클라이언트 코드를 변경하지않고, 클라이언트가 호출하는 대상의 타입 인스턴스를 변경 할 수 있다.
  • 의존관계 주입을 사용하면 정적인 클래스 의존관계를 변경하지 않고, 동적인 객체 인스턴스 의존관계를 쉽게 변경 할 수있다.
    ex) 구현객체를 어떤것으로 할지

IOC, DI 컨테이너

AppConfig처럼 객체를 생성하고 관리하면서 의존관계를 연결해주는것을 컨테이너라고한다.

 

 

 

강의출처 : 스프링 핵심 원리 - 기본편 - 인프런 | 강의 (inflearn.com)

좋은 객체 지향 설계 5가지 원칙 정리

  • SRP : 단일 책임 원칙(Single responsibility principle)
    • 한 클래스는 하나의 책임만 가져야한다.
    • 변경이 있을때 파급 효과가 적으면 단일 책임원칙을 잘따른것 
  • OCP : 개방-폐쇄 원칙(Open/closed principle) *중요!
    • 소프트웨어 요소는 확장에는 열려 있으나, 변경에는 닫혀있어야한다.
    • 인터페이스를 구현한 새로운 클래스를 하나 만들어 새로운 기능을 구현(다형성)
  • LSP : 리스코프 치환 원칙(Liskov substitution principle)
  • ISP : 인터페이스 분리 원칙(Interface segregation principle)
    • 각기능에 맞는 인터페이스 분리
    • 인터페이스가 명확해지고, 대체 가능성이 높아진다. 
  • DIP : 의존관계 역전 원칙(Dependency inversion principle) *중요!
    • 역할에 의존하여야한다
    • interface만 알아야지 그 외 구현까지는 관계를 인지하지 않아도된다.
    • 역할과 구현을 철저히 분리, 추상화에 의존해야하지 구체화에 의존하면안된다.
    • ex) MemberService 클래스에서 MemberRepository m = new MemoryMemberRepository(); DIP위반

ex) 

ex) DIP 준수시 private DiscountPolicy discountPolicy;

 - 인터페이스에만의존시 Test 시 discountPolicy => Null PointerException 발생

 

ex) 생성자 주입으로 역할과 구현 분리!!

 

※ 기존 개인프로젝트 및 팀프로젝트는 내가 생각한대로 만들었기 때문에 구현체를 변경하는 일이없었다.

    현재 Spring 강의에서는 회원(VIP)에 대해 변경사항(1000원 할인 또는 10%할인)이 발생한다는 가정으로 만들었다.

    이경우 생성자 주입이 아주용이하게 사용이된다.

 

  기존사용방식 

  1. @Autowired  
  2. @RequiredArgsConstructor

 

강의출처 : 스프링 핵심 원리 - 기본편 - 인프런 | 강의 (inflearn.com)

스프링 프레임워크

  • 핵심기술 : 스프링 DI 컨테이너, AOP, 이벤트, 기타
  • 웹 기술 : 스프링 MVC, 스프링 WebFlux
  • 데이터 접근 기술 : 트랜잭션, JDBC, ORM지원, XML지원
  • 기술 통합 : 캐시, 이메일, 원격접근, 스케줄링
  • 테스트 : 스프링 기반 테스트 지원
  • 언어 코틀린, 그루비
  • 최근에는 스프링 부트를 통해서 스프링 프레임워크의 기술들을 편리하게 사용

 

스프링 부트

  • 스프링을 편리하게 사용할 수 있도록 지원, 최근에는 기본으로 사용
  • 단독으로 실행할 수 있는 스프링 애플리케이션을 쉽게 생성
  • Tomcat 같은 웹 서버를 내장해서 별도의 웹 서버를 설치하지 않아도 됨
  • 손쉬운 빌드 구성을 위한 Starter 종속성 제공

      - Spring Boot 사용시 라이브러리 하나만 설정을 하면 관련된 라이브러리가 모두 설치가 된다.

      - Spring 라이브러리 설정시 Connection Pool 및 mybatis 등등 여러 라이브러리를 한번에 설정시 에러가 발생했던 기억

        이 난다. 이때는 왜 에러가발생했는지 몰랐다....;

  • 스프링과 3rd parth(외부) 라이브러리 자동 구성

      - Spring은 라이브러리 설정시 버전의 영향을 많이 받았는데 Spring Boot는 그렇지않다.

  • 메트릭, 상태확인, 외부 구성 같은 프로덕션 준비 기능 제공

스프링과 객체 지향

  • 다형성이 가장 중요하다.
  • 스프링은 다형성을 극대화해서 이용할 수 있게 도와준다.
  • 스프링에서 이야기하는 제어의 역전(IOC), 의존관계 주입(DI)은 다형성을 활용해서 역할과 구현을 편리하게 다룰 수 있도록 지원한다.
  • 스프링을 사용하면 마치 레고 블럭 조립하듯이 공연 무대의 배우를 선택하듯이 구현을 편리하게 변경할수있다.

      - 프로젝트시 Interface(Repository)만 변경하면 기능이 변경된다.

 

 

강의출처 : 스프링 핵심 원리 - 기본편 - 인프런 | 강의 (inflearn.com)

+ Recent posts