본문 바로가기

WINK-(Web & App)/Spring Boot 스터디

[2024-2 SpringBoot 스터디] 정호용 #3주차 섹션 1~3

반응형

섹션 2. 객체 지향 설계와 스프링

- 스프링이란?

스프링 --> 여러 기술의 모음

스프링 프레임워크 --> 스프링의 핵심

스프링부트 --> 스프링을 더 쉽게

스프링 데이터 --> RDB 의 CRUD는 비슷함. 이를 편리하게 쓰게 하기 위한 것. 스프링 데이터 JPA가 제일 많이 쓰임

 

스프링 프레임워크가 제일 중요!

이 안에는 핵심 기술, 웹 기술, 데이터 접근 기술 등이 들어있음

스프링부트 --> 스프링을 편리하게 사용할수 있도록 지원

- Tomcat 웹 서버 내장

- starter 종속성 : jpa, aop 등의 라이브러리를 쓸 때 하나만 가져오면 나머지를 가져오게 됨

- 스프링과 3rd party 라이브러리 자동 구성

- 관례에 의한 간결한 설정

 

스프링이라는 단어는 문맥에 따라 다르게 사용됨

- 스프링 DI 컨테이너 기술

- 스프링 프레임워크

- 스프링부트, 스프링 프레임워크 모두 포함한 스프링 생태계

 

스프링의 핵심?

- 스프링은 자바 언어 기반의 프레임워크

- 자바? 객체지향 언어

- 스프링은 객체지향 언어가 가진 강력한 특징을 살려내는 프레임워크

- 스프링은 좋은 객체지향 어플리케이션을 개발할 수 있게 도와주는 프레임워크

- 좋은 객체 지향 프로그래밍이란?

객체지향 프로그래밍?

- 컴퓨터 프로그램을  "객체" 들의 모임으로 파악하고자 하는 것.

- 각각의 객체는 메시지를 주고받고, 데이터를 처리

- 객체지향 프로그래밍은 프로그램을 유연하고 변경이 용이하게 함. - 레고블럭 조립하듯이, 컴퓨터 부품 교체하듯이

 

다형성?

- 예를 들어, 자동차가 여러 가지 있는데, 운전자가 자동차를 바꿔도 자동차의 역할은 변하지 않는다.

- 클라이언트에 영향을 주지 않고 새로운 기능을 제공 가능하다.

 

역할-구현 구분

- 클라이언트는 대상의 역할(인터페이스)만 알면됨

- 클라이언트는 구현 대상의 내부 구조를 몰라도 됨

- 클라이언트는 구현 대상의 내부 구조가 변경되어도 영향받지 않음

- 클라이언트는 구현 대상 자체를 변경해도 영향받지 않음

 

역할 = 인터페이스

구현 = 인터페이스를 구현한 클래스, 구현 객체

구현 < 인터페이스

 

다형성의 본질

- 인터페이스를 구현한 객체 인스턴스를 실행 시점에 유연하게 변경 가능

- 다형성의 본질을 이해하려면 협력이라는 객체사이의 관계에서 시작해야 함

- 클라이언트 변경 없이 서버의 구현 기능을 유연하게 변경 가능

 

결론

- 인터페이스를 안정적으로 잘 설계하는 것이 중요

- 무조건 역할-구현 분리가 좋진 않다. 인터페이스 자체가 변하면?

 

스프링과 객체 지향

- 다형성이 제일 중요

- 스프링은 다형성을 극대화해서 이용할 수 있게 지원

- 스프링의 IoC(제어의 역전) DI(의존관계 주입) 은 다형성을 활용해 역할-구현을 편하게 다룰 수 있도록 지원

- 스프링 사용 시 구현을 편리하게 변경 가능

- 좋은 객체 지향 설계의 5가지 원칙(SOLID)

SOLID란? 클린코드로 유명한 로버트 마틴이 좋은 객체지향 설계의 5가지 원칙을 정리

1. SRP - 단일 책임 원칙

- 하나의 클래스는 하나의 책임

- 그러나 책임이 모호함 : 책임이 클수도, 작을수도 있고, 문맥과 상황에 따라 다르다.

- 중요한 기준은 변경임 - 변경이 있을 때 파급 효과가 적으면 SRP를 잘 따른 것

- 책임의 범위를 적절히 정하는 것도 중요함.

 

2. OCP - 개방-폐쇄 원칙

- 제일 중요한 원칙, 소프트웨어 요소는 확장에는 열려있고, 변경에는 닫혀 있어야 한다.

- 이해가 안 된다면, 다형성을 생각해 보자. 인터페이스를 구현한 클래스를 만드는 것은 확장이다. (기존 코드 변경 없음)

- 문제점? 클라이언트가 구현 클래스를 직접 선택 --> 구현 객체 변경 시 클라이언트 코드를 변경해야 함

- 이는 다형성을 사용했지만, OCP 원칙에는 위배된다.

- 객체를 생성, 연관관계 맺어주는 별도의 설정자 필요 --> 스프링이 이를 담당

 

3. LSP - 리스코프 치환 원칙

- 프로그램의 객체는 프로그램의 정확성을 깨트리지 않아야 함 --> 자동차 인터페이스의 엑셀은 앞으로 가는 기능인데, 뒤로 가게 구현하면 LSP 위반이다.

 

4. ISP - 인터페이스 분리 원칙

- 특정 클라이언트를 위한 인터페이스 여러 개가 범용 인터페이스 하나보다 낫다.

- 자동차 인터페이스만 있다면 너무 큼 --> 이를 운전 인터페이스와 정비 인터페이스로 분리한다.

- 사용자 클라이언트는 운전자 클라이언트와 정비사 클라이언트로 분리

- 정비 인터페이스가 바뀌어도 운전자 클라이언트에 영향 없음 

 

5. DIP - 의존관계 역전 원칙

- 이것도 중요한 원칙 중 하나

- 구현 클래스에 의존하지 말고, 인터페이스에 의존해야 함. 즉, 구체화에 의존하지 말고, 추상화에 의존해야 함.

- 다형성에 의해 DIP 위반함.

 

다형성이 객체지향의 핵심이지만, 이것 만으로는 OCP와 DIP를 지킬 수 없다.

 

- 객체 지향 설계와 스프링

- 스프링에 객체지향 얘기가 왜 나왔냐?

- 스프링은 다형성 + OCP + DIP를 가능하게 지원

- DI(Dependency Injection) : 의존성 주입

- DI 컨테이너 제공

 

- 인터페이스를 먼저 설계하고 구현체로 구현하자!

- 다만, 인터페이스 도입 시 추상화라는 비용 발생

 

섹션 3. 스프링 핵심 원리 이해1 - 예제 만들기

- 비즈니스 요구사항과 설계

회원 도메인 설계?

- 회원 도메인 요구사항

1. 회원가입 및 조회

2. 회원은 일반과 VIP등급

3. 회원 데이터는 자체 DB 혹은 외부시스템과 연동 가능(미확정)

* 회원 서비스 : MemberServiceImpl

 

 

주문/할인정책?

1. 회원은 상품 주문 가능

2. 회원 등급에 따른 할인정책 적용 가능

3. 할인 정책은 모든 VIP는 1000원 할인 (변경될수도)

4. 할인 정책은 변경가능성 높음. 미확정

 

- 회원 도메인 개발

- Interface

MemberRepository.java MemberService.java
 

 

- 구현체

Member.java MemberServiceImpl.java MemoryMemberRepository.java

 

- 회원 도메인 실행과 테스트

현재 이 코드는 순수 java만을 이용해서 테스트 코드를 만들었다.

이번엔 JUnit을 이용해서 만들어보도록 하자.

given / when / then 패턴으로 junit 테스트 코드를 짠 다음에 실행해 주면 된다.

 

회원 도메인 설계에서...

DIP를 위배하지 않았는가..? --> 위배했다.

 

- 주문과 할인 도메인 설계

클라이언트 -> 주문 서비스 역할 -> 할인 정책역할

                                                 -> 회원 저장소 역할

 

주문 도메인 객체 다이어그램

클라이언트 -> 주문 서비스 구현체 -> 메모리 회원 저장소

                                                    -> 정액 할인 정책

 

*정률 할인 정책을 바꿔도 구현체만 바꾸면 됨

 

주문 도메인 객체 다이어그램 2

클라이언트 -> 주문 서비스 구현체 -> DB 회원 저장소

                                                    -> 정률 할인 정책

 

- 주문과 할인 도메인 개발

- 멤버 등급에 따른 할인 구현

(Interface)DiscountPolicy.java (Class)FixDiscountPolicy.java

 

- 주문

(Class)Order.java (Interface)OrderService.java



(Class)OrderServiceImpl.java
생성자, getter, setter생성, 할인 있는 경우 할인가 포함해 가격 리턴 각각 인터페이스와 구현체 작성

 

- 주문과 할인 도메인 실행과 테스트

java로만 테스트 junit테스트

 

반응형