Spring boot

[기본] 스프링 핵심 원리 이해2 - 객체 지향 원리 적용

cme10575 2021. 8. 6. 20:26

메모

ctrl + shift +T : Create new test

 

Create Test, JUnit5로 지정

@DisplayName("") JUnit5 부터 지원하는 기능, 해당 이름으로 테스트 결과 출력됨

항상 실패 테스트도 해봐야 한다.

Assertions는 static으로 import하는게 좋다.

final은 무조건 값이 할당되어야 함

ctrl + E : history

ctrl + alt + m : extract method (함수뽑기)

리턴타입은 인터페이스를 선택

인터페이스는 아무곳에도 의존하고 있지 않다.

 

다이어그램 의존하는쪽에서 화살표 출발한다.

 


새로운 할인 정책과 문제점

기획자가 기존 할인 정책 대신 새 정책을 적용할 것을 요구

"계획에 따르기보다 변화에 대응하기를" - 애자일 소프트웨어 개발 선언https://agilemanifesto.org/iso/ko/manifesto.html

 

애자일 소프트웨어 개발 선언

애자일 소프트웨어 개발 선언 우리는 소프트웨어를 개발하고, 또 다른 사람의 개발을 도와주면서 소프트웨어 개발의 더 나은 방법들을 찾아가고 있다. 이 작업을 통해 우리는 다음을 가치 있게

agilemanifesto.org

DiscountPolicy를 의존하는 RateDiscountPolicy 생성

 

그러나 이 클래스를 적용하려면 클라이언트인 OrderServiceImpl을 고쳐야 함 -> OCP, DIP위반

 


관심사의 분리

구현 객체를 생성하고 연결하는 책임만 가지는 별도의 클래스 AppConfig를 만들자 

생성자를 통해서 객체 인스턴스의 참조를 주입하자 -> "Dependency Injection"

 

이제 구성은 사용 영역과 구성 영역 두 가지로 분리되었다.

할인 정책을 변경하여도 클라이언트 코드를 포함하는 사용 영역은 어떤 코드도 변경할 필요가 없다.

 


좋은 객체 지향 설계의 5가지 원칙 적용

SRP - 객체를 생성 연결/ 실행하는 책임으로 분리함

DIP - "추상화에 의존해야지, 구체화에 의존하면 안된다", 클라이언트가 추상 인터페이스에만 의존함

OCP - "소프트웨어 요소는 확장엔 열려있고 변경엔 닫혀 있어야 한다", 클라이언트 코드를 수정하지 않아도 된다.

 


IoC, DI, 그리고 컨테이너

제어의 역전(Inversion of Control)

기존 프로그램은 클라이언트 객체가 스스로 객체를 생성하고 연결하고 실행했다.

반면에 AppConfig 이후에는 자신의 로직 실행만 담당한다.

제어의 흐름은 AppConfig가 가져간다.

 

이렇게 외부에서 흐름을 제어하는 것을 IoC라고 한다.

 

프레임워크 등이 대신 흐름을 담당하는 것이 여기 해당

 

프레임워크: 라이프사이클이 있고 그 안에서 콜백식으로 나의 코드를 실행시킴 (제어의 역전)

라이브러리: 개발자가 직접 흐름을 담당(호출하여 사용)

 

 

의존관계 주입(Dependency Injection)

의존관계는 정적인 클래스 의존관계와, 실행 시점에 결정되는 동적인 객체(인스턴스)의존 관계 둘이 있다.

 

어플리케이션 실행 시점(런타임)에 외부에서 객체를 생성하고 참조값을 전달하여 연결하는 것을 의존관계 주입이라고 한다.

 

 

컨테이너

AppConfig처럼 객체를 생성, 연결하는 것을 IoC 컨테이너 혹은 DI 컨테이너 혹은 어샘블러라고 한다.

 


스프링으로 전환하기

AppConfig에 @Configuration, 각 메소드에 @Bean 어노테이션을 붙인다.

main에서 AnnotationConfigApplicationContext를 생성하고 getBean을 통해 키값으로 원하는 객체를 가져온다.

 

스프링 컨테이너에 등록 시 기본적으로 메소드 이름으로 등록되며 꺼내갈 때 메소드 이름을 키로 가져간다.