Skip to content

Latest commit

 

History

History
210 lines (124 loc) · 8.94 KB

TIL220309.md

File metadata and controls

210 lines (124 loc) · 8.94 KB

Daily to do list

Java


Spring


CS


알고리즘


오늘의 회고

220308-2 Spring

————————— 스프링 순수 예제

설정에서 gradle을 intelliJ로 컴파일러를 바꿈 더 빨라서?

비즈니스 요구사항과 설계

회원, 주문과 할인 정책

회원 = 가입, 조회, 등급(일반,VIP), 자체 DB구축 or 외부 시스템 연동 주문 = 상품 주문, 할인정책(변경할수도있음)

요구사항이 결정이 안난 부분이 많아서 객체 지향으로 설계 해야함

인터페이스를 만들고 구현체를 언제든지 갈아끼울 수 있도록 설계!!!!

백문이불여일타..

???? 게터 세터로 접근하는

옵션 + 엔터 = 에러 메세지 확인

??? 컨커런트 해시맵 동시성 이슈

하지만 이러한 설계의 문제는??

OCP, DIP 생각해보면 둘 다 문제가 걸림 서비스에서 가르키는건ㅅ이 인터페이스가 아니라 객체를 가르킴 즉 역할을 가르키는 것이 아닌 구현을 가ㄹ키고 있어서 둘 다 위반

——————————————— 주문과 할인 도메인 설게

주문 = 상품 주문, 할인정책(변경할수도있음)

변동이 있기에 좋은 객체 지향 설계가 필요하다 원래도 필요하지만….

 역할을 먼저 만들고 구현체를 만들어야함 역할과 구현을 분리해서 자유롭게 구현 객체를 조립할 수 있게 설계. 할인 정책도 유연하게 변경할 수 있다.  역할들의 협력 관계는 그대로 재사용 할 수 있다.

/** 치면 주석이 자동으로 나옴 변수들과 리턴값도

커멘드 + N = toString도 있음 psvm = 메인 클래스

?????? long, Long 차이 널이 들어가는지? 래퍼 타입?

————————— 새로운 할인 정책 개발

지금처럼 고정이 아닌 퍼센트로 할인을 하는 방법으로 변경하고 싶다고 기획자가 전달..

커맨드 + 쉬프트 + T = 테스트 소스 맏늘어줌

테스트 케이스를 만들 떄 Assertions 같은 것은 static import해도 좋다. 생략가능해서

  • 새로운 할인 정책 적용 문제점 할인 정책을 변경하려면 클라이언트인 OrderServiceImpl 코드를 고쳐야 한다. ** 우리는 역할과 구현을 충실하게 분리했는가? ok ** 다형성도 활용하고, 인터페이스와 구현 객체를 분리했는가? ok ** OCP, DIP 같은 객체지향 설계 원칙을 충실히 준수했는가? 이게 사실 아님  실제는 이렇게 구현 클래스도 같이 의존한다!! DIp 위반!

 그리고 이 할인 정책을 바꾸는 순간을 보면 클라이언트의 소스를 변경해야 한다!! 즉 OCP위반! 예로) 자동차를 기름차에서 전기차로 바꾸는데 내가 라이센스를 뭔가 바꿔야하 하는 상황?..

???? final 변수... 알아봐야함

해결 방법은? 이 문제를 해결할려면 누군가 클라이언트인 OrderServiceImpl에 DiscountPolicy의 구현 객체를 대신 생성하고 주입해주어야 한다.!!

관심사분리

위 문제는 연극에서 남자 배우가 여자 배우를 직접 선택하는 것과 같다 이런 경우 남자 배우가 연극도 해야하지만 초빙도 해야하는 “다양한 책임”을 갖게 된다. 즉 관심사를 ,책임을 분리해줘야 한다. 공연 기획자와 배우로 관심을 나눠야 한다.

  • AppConfig의 등장 애플리케이션의 전체 동작 방식을 구성(config)하기 위해, “구현 객체를 생성”하고 연결하는 책임을 가지는 별도의 설정 클래스

생성자 주입, 생성자를 통해서 주입이 된다. 기존에서는 ServiceImpl에서 객체까지 참조하고 있었는데 그 부분을 생성자를 통해서 참조하도록 변경해주고 AppConfig에서 어떠한 것을 참조할지 설정을 해주도록 바꿔주면은 ServiceImpl이라는 클라이언트에서는 소스가 바뀌는 것이 없게 된다. 이러한 것을 생성자 주입이라고 한다.

Appconfig는 애플리케이션의 실제 동작에 필요한 구현 객체를 생성한다. (기존에는 서비스 안에서 해서 역할과 구현까지 참조해서 DIP, OCP 가 위반되었음)

Appconfig는 생성한 객체 인스턴스의 참조를 ‘생성자를 통해 주입’ 보면 생성자를 만들면서 객체를 넣어 줌 즉 이것만 바꾸면 됨 ㅎ 이건 생성자 주입이라고 함

이렇게 변경하여 ServiceImpl은 객체에 의존하지 않고 인터페이스에만 의존! ServiceImpl입장에서는 생성자를 통해 어떤 구현 객체가 들어올지(주입될지) 모름 ServiceImpl의 생성자를 통해서 어떤 구현 객체가 주입할지 오직 AppConfig에 의해 결정(공연기획자 느낌 아까 ) ServiceImpl는 이제부터 의존관계에 대한 고민 없이 실행에만 집중하면 된다.

 객체의 생성과 연결은 AppConfig 담당, DIP 완성! 관심사 분리: 객체를 생성하고 연결하는 역할과 실행하는 역할이 명확하게 분리되었다.

 이렇게 AppConfig가 memoryMemberRepository를 생성하고 그 참조값을 memberServiceImpl에 생성하면서 주입한다.

클라이언트인 “memberServiceImpl”입장에서 보면 의존관계를 마치 외부에서 주입해주는 것 같다고 해서 “DI” 우리말로는 의존관계 주입, 의존성 주입이라고 한다.

커맨드 + E = 최근 열었던 파일

Appconfig 리팩터링

현재 중복, 역할도 한 눈에 딱 안보임

옵션 + 커맨드 + M = 리팩터링을 시켜줌 역할별로 묶어줌

new MemoryMemberRepository() 라는 중복이 있었다 이것은 서비스 단위로 AppConfig가 있어서 그랬던 것인데.. 이걸 합쳐주면 오히려 역할에 따라 구분이 되어 알아보기도 더 쉽다.

기존에는 서비스 단위로 Appconfig가 구분되어 있었는데 이렇게 되면 역할에 따라 보는 것이 한 눈에 안들어옴 그래서 이걸 역할 단위?로 바꿔주면 됨.

AppConfig가 등장하면서 사용 영역과 구성 영역으로 분리가 된다. 

구성영역은 당연히 변경된다. 구성 역할을 담당하는 AppConfig를 애플리케이션이라는 공연의 기획자로 생각하면 편하다.

이것으로 보면 DI를 통해서 OCP도 지켰고 DIP를 지켰다.

전체 흐름 정리

새로운 할인 정책 개발… 할려고 했음 추가 개발은 문제가 없었다..

하지만ㅇ ㅣ것이 문제점은 클라이언트 코드인 주문 서비스 구현체도 함께 변경했어야 했다 ( OCP위반) 주문 서비스 클라이언트가 인터페이스뿐만 아니라 구현체도 같이 참고하고 있었음 (DIP 위반)

관심사의 분리가 필요하였음 애플리케이션을 공연이라고 생각하면 기존에 남자 배우가 기획일까지 하고 있었음.. 이것은 단일 책임 원칙도 위반되기도 함

즉 이것을 공연을 구성하는 역할을 하는 공연 기획자가 필요했었음 이 개념이 AppConfig임 이 객체가 공연 기획자 역할을 해줌.. 이것으로 인해 클라이언트 객체는 자신의 역할을 실행하는 것만 집중하고 권한과 책임이 줄어듬

appconfig 리펙터링 구성 정보에서 역할과 구현을 명확하게 분리 중복도 제거 이렇게 해서 한 눈에 알아보기 쉬워짐

새로운 구조와 할인 정책적용 이걸 많은 것을 바꾸지 않고 AppConfig의 구성 영역만 바꾸면 전부 다 그대로 돌아감. 가장 중요한 것은 클라이언트 영역 코드를 바꾸지 않아도 됨

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

여기서는 3가지 단일 책임원칙, 개방폐쇄원칙, 의존관계 역전 원칙

  • 단일 책임 “한 클래스는 하나의 책임만 가져야 한다.”

클라이언트 객체는 직접 구현 객체를 생성하고 연결하고 실행하는 다양한 책임을 갖고 있었다 관심사 분리를 통해서 단일 책임을 주었다. 구현 객체를 생성하고 연결하는 책임은 AppConfig가 담당, 실행은 클라이언트가 담당,.!

  • 의관관계 역전 “프로그래머는 추상화에 의존, 구체화에 의존하면 안된다,” 의존성 주입은 이 원칙을 따르는 방법 중 하나

기존 ServiceImpl는 DIP를 지키는 것 같았지만 구현 클래스까지 의존하고 있었다… 하지만 클라이언트 코드는 인터페이스만으로는 아무것도 실행할 수 없다. 이것을 AppConfig가 객체 인스턴스를 클라이언트 코드 대신 생성해서 클라이언트 코드에 의존관게 주입을 해주었다. DI

  • 개방 폐쇄 다형성 사용하고 클라이언트가 DIP를 지킴 애플리케이션을 사용 영역과 구성 영역으로 나눔 AppConfig가 의존관계를 변경하여도 클라이언트 코드에 주입하므로 클라이언트 코드는 변경하지 않아도 됨. 즉, 소프트웨어 요소를 새롭게 확장해도 사용 영역의 변경은 닫혀 있다!!

————————————— IoC, DI, 컨테이너