Spring

[Spring] 스프링 핵심 원리(기본편) 강의정리 - 1

haenni 2023. 11. 22. 17:48

🌱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);