스프링에서 OOP와 안티 패턴 : Transaction script

존스노우·2023년 10월 22일
0
post-thumbnail
  • 백엔드 한테 ui란 ? controller!

  • relaxed 아키텍쳐 좋지 않은 방식

  • 도메인 레이어?
  • 애플리케이션의 핵심

  • 어우 좋지 않다
  • 응용계층은 최대한 얇게
  • 오직 작업 조정 밑 아래 위치한 계층에 도메인 객체 협력자 작업 위임?
  • 이해하기 어렵군

  • 트랜잭션 스크립트.. 흐음
  • 그리고 바로 JPA 레파지토리 접근? 아직까진 이거에대해 비판인대
  • 실무에선 바로사용하긴 하는데..
  • 아무튼 비즈니스 로직은 도메인이 들고 있게!

뚱뚱한 서비스 위에 말한 안안좋 서비스에 문제점?

  • 테스트 코드 작성시 -> 비즈니스 로직과 레포지토리가 결합되어 있다.

  • 도메인이 비즈니스 로직을 들고 있으니 테스트가 좀 쉬워졌다?
  • 서비스 책임을 객체로 위임

  • 애매한 경우??
  • 어디든 들어가도 어색하다

  • 새로운 도메인 만들어 주기!
  • 이런걸 도메인서비스다.
  • 보통 Manger 라고 칭한다.
  • 스프링에서말한 서비스랑 이름이 겹치니 애플리케이션 서비스라 칭하고
  • 우리가 만든건 도메인 서비스
  • 애플리케이션 서비스는 결국 책임을 도메인 서비스나 도메인으로 위임하는게 서비스 역할

  • 참 정리 잘되어있다.
  • 현재 작은 프로젝트라 트랜잭션 스크립트 스러운면이있는대.
  • 후 잘 적용하면서 바꿔 나가야겠다.

어디까지 추상화 해야하지?

  • 모듈을 격리하고 인터페이스를 만드는 과정
  • 책임을 선별하는 과정
  • 어디까지 추상화를 해야 될까?

  • 이런식으로 분할 하자
  • 전 회사 프로젝트가 이런 의도 였는대 다시한번 상기시켜보자

  • DB Entity 와 도메인 Entity를 분리함
  • 의존성 역전의 법칙!

뭐가 좋을까?

  • 결합도가 낮아짐

  • 이런식으로 바뀌면 개방폐쇄의 원칙이 지켜지면서 어떤레파지토리로 변경해도 가능

  • mock 레포지토리 도 가능

  • 설계를 통해 테스트를 쉽게!

왜 굳이 레포지토리 인터페이스를 비즈니스 로직으로 옮김?

  • 고수준 모듈이 저수준모듈을 의존하지 않게 하는 것?

  • 현재 그림상황보면 고수준 비즈니스 레이어가 persistence 계층을 의존하고 있다

  • 그래서 이런식으로 구조 변경

  • 대표적인 외부 통신인 레스트 클라이언트나 웹클라이언트도 추상화를 해주자

서비스도 추상화해서 의존역전 만들면?

  • 서비스는 굳이 추상화 하지맙시다 강의에서 나오는데 .

  • 컨트롤러 서비스 앤티티 vo는 구현체로 구현되어도 상관없다 왜?
  • 한번 생성으로 영원히 같은일을 하는 객체어야 하기 때문
  • 다음 강의 때 자세히
  • 여기서 일단 결론은 서비스는 구현체여도 상관없지만 레포지토리는 추상화를 해야한다.

  • 도메인이 계층을 추가하자!

  • 레포지토리가 위로 올라 왔네?

  • 즉 도메인객체는 레포지토리를 사용 못함

  • 도메인 객체가 협력에 필요한 모든객체는 애플리케이션 서비스에 미리 다준비해서 도메인에게 넘겨줘야 함.

  • 이해하기 어려운 구문들 ㅠㅠ

  • 원친적으로 도메인과 도메인서비스는 레포지토리를 알아서 안돼지만

  • 불필요한 쿼리가 나가는 상황이 존재

  • 그래서 접근가능하게해서 따로

  • 이런식으로 접근하게 만들어야 한다.

서비스란 무엇일까?

  • 스프링은 왜이런 이름으로 어노테이션을 만들까?


  • 주석에 내용
  • 서비스는 DDD에서 가져온 개념이고 비즈니스 서비스의 Facade 임
  • 즉 스프링은 DDD를 DDD답게 사용하기 위한 프레임 워크
  • 비즈니스 서비스 파사드? 도메인은 비즈니스 로직을 객들고 있는 객체!
  • 도메인과 도메인 서비스에게 책임을 위임하는 Facade 패턴의 일종이라고 할 수 있음

  • DDD에서 정의하는 서비스란

  • 행위자 Manager .. 흠 ( 적당한 이름이 없어서 붙이는데 !?)

  • 객체간의 협력을 좀더 강조하는 느낌의 Service라는 이름이 더 적합한거 같다

  • 즉 서비스는? 매니저이다 !

  • 이런식으로 정리

서비스 관련 조언

  • 첫 번째 객체는 생성하면 여러 번 사용하지만 자신을 바꿀 수 없음 , 생명 주기단순
  • 한번 생성하면 특정 작업을 하는 기계처럼 영원히 실행 하는 객체를 서비스라 함
  • 영원히는 불변 그럼 불변성을 유지하려면?

  • 멤버 변수는 불편
  • 스프링이 필드 주입을 지양하고 생성자 주입을 권장하는 이유
  • 서비스는 불변이어야 함으로

tips

  • 자바측에서 정한 기술 명세..

  • 관계에 있어서 가장 중요한 컬럼은 외래키이기 때문에 관계의 주인이라 함
  • 그래서 외래키를 소유하고있느쪽을 연관관계의 주인
  • maapedBy는 실제 연관관계 주인을 알려주는 지표

n+1?

  • 패치타입을 잘못설정해서 아니?
  • 지연이던 즉시 로딩이던 n=1은 발생

  • 이미알던 내용

  • 팀을 가져오는 쿼리 + 팀에 소속된 직원을 가져오는 쿼리를 한번더 ?
  • 이러면 구조적으로 해결

  • IDE 추천방식을 따르면 중간은 간다

낙관적 비관적 잠금

  • update 시 경합 발생시 둘 중 하나 실패하게 만드는
  • 충돌방지

  • 트랜잭션 공부하다 보면 나오는 내용들
  • 메서드에 걸린 에노테이션을 타려면 스프링 프록시를 거쳐야되는대
  • 내부 호출로는 프록시를 타지않아 어노테이션이 적용되지 않아

  • 이련경우는 없지만 일단 체크

  • 으음 괜찮은 방법 인거 같음
  • 지금 api 테스트는 실제 디비를 사용하는데 이런 로컬디비 구현으로 빠르게 해도 괜찮지 않을까?
profile
어제의 나보다 한걸음 더

0개의 댓글