[Spring] 스프링 핵심 원리(기본편) 강의정리 - 1
🌱Spring - 객체 지향 설계와 스프링
📖 스프링이란?
"Spring"이란 여러 기술들의 모음이다.
필수적인 기술로 스프링 프레임 워크 와 스프링 부트 가 있다
📖 좋은 객체 지향 프로그래밍이란?
- 프로그램을 유연하고 변경이 용이하게 만들어야 함
- 다형성을 지키는 것이 중요함
- 인터페이스를 잘 설계하는 것이 좋은 객체 지향 프로그래밍
📖 좋은 객체 지향 설계의 5가지 원리(SOLID)
- SRP: 단일 책임 원칙(single responsibility principle)
- OCP: 개방-폐쇄 원칙 (Open/closed principle)
- LSP: 리스코프 치환 원칙 (Liskov substitution principle)
- ISP: 인터페이스 분리 원칙 (Interface segregation principle)
- DIP: 의존관계 역전 원칙 (Dependency inversion principle)
예제 만들기
📖 비즈니스 요구사항과 설계
:요구사항을 참고하여 프로젝트를 만든다

📖 회원 도메인 설계
:회원 도메인


📖 회원 도메인 개발
:src/main/java/hello.core/member
Grade.Enum - 회원 등급
Member.java - 회원 엔티티
MemberService.interface - 회원 서비스 interface
MemoryMemberService.jajva - 회원 서비스 구현체
MemberRepository.interface - 회원 저장소interface
MemoryMemberRepository.java - 회원 저장소

📖 주문과 할인 도메인 설계
:주문과 할인 정책

📖 주문과 할인 도메인 개발
:src/main/java/hello.core/discount

객체 지향 원리 적용
📖 새로운 할인 정책 개발
:주문한 금액의 %를 할인해주는 새로운 정률 할인 정책을 추가

📖 새로운 할인 정책 적용과 문제점
:주문한 금액의 %를 할인해주는 새로운 정률 할인 정책을 추가
- 기존의 VIP 등급이면 1,000원을 할인해주는 정책에서 VIP등급이면 구입한 금액의 10%를 할인 해주는 정책으로 변경했다고 가정 -
FixDiscountPolicy() - 1,000원을 할인해주는 정책
RateDiscountPolicy() - 10%를 할인 해주는 정책
// 변경 전
private final DiscountPolicy discountPolicy = new FixDiscountPolicy();
// 변경 후
private final DiscountPolicy discountPolicy = new RateDiscountPolicy();
interface에 의존하고 있을 뿐만 아니라 구현클래스(구체클래스) 에도 의존하고 있다는 문제점이 있다. -> DIP, OCP 위반
(구현클래스에도 의존 할 경우 클라이언트 OrderService.java, MemberService.java 등의 코드도 수정해야 하는 불편함이 있다.)
이를 해결하기 위해 interface에만 의존하도록 변경해야 한다.
// 수정 후
private DiscountPolicy discountPolicy;
-> 구현클래스(구체클래스)에 의존하고 있지않지만 DiscountPolicy()는 구현되지 않은 interface이기에 오류 발생
📖 관심사의 분리
:애플리케이션의 전체 동작 방식을 구성하기 위해, 구현 객체를 생성하고, 연결하는 책임을 가지는 별도의 설정 클래스인 "Appconfig" 를 생성한다.
AppConfig - 구현 객체 생성 및 생성자 주입
📖 AppConfig 리팩터링
:AppConfig의 중복 코드를 수정해주며 가독성을 높여준다(역할에 따른 구현이 잘 보이도록).
public class AppConfig {
// MemberService -> memberRepository()
public MemberService memberService() {
// 생성자 주입
return ...
}
// OrderService -> memberRepository(), discountPolicy()
public OrderService orderService() {
// 생성자 주입
return ...
}
// memberRepository()
public MemberRepository memberRepository() {
return ...
}
// discountPolicy()
public DiscountPolicy discountPolicy() {
return ...
}
}
📖 새로운 구조와 할인 정책 적용
:할인 정책 수정 ( AppConfig만 수정하여 할인 정책을 적용 할 수 있음 )
// discountPolicy()
public DiscountPolicy discountPolicy() {
// return new FixDiscountPolicy();
return new RateDiscountPolicy();
}
📖 스프링으로 전환하기
:AppConfig를 스프링 기반으로 변경
/*AppConfig는 애플리케이션의 실제 동작에 필요한 "구현 객체를 생성"한다
* AppConfig는 생성한 객체 인스턴스의 참조(래퍼런스)를 "생성자를 통해 주입"한다
*/
@Configuration // 설정 정보, 구성 정보
public class AppConfig {
@Bean // 스프링 컨테이너에 등록 (각 메서드에 @Bean이라고 적어야 함 (SpringBean의 이름은 메소드 이름 이다.)
// MemberService -> memberRepository()
public MemberService memberService() {
// 생성자 주입
return ...
} ...
변경후 , App에 스프링 컨테이너를 적용한다.
// 스프링 컨테이너 사용
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class); //스프링은 모든게 ApplicationContext로 시작한다(모든 걸 관리해줌)
MemberService memberService = applicationContext.getBean("memberService", MemberService.class);
OrderService orderService = applicationContext.getBean("orderService", OrderService.class);