Open nuagenic opened 7 months ago
1) 유즈케이스 참고 링크 : https://velog.io/@bky373/Architecture-%ED%81%B4%EB%A6%B0-%EC%95%84%ED%82%A4%ED%85%8D%EC%B2%98%EC%9D%98-%ED%95%B5%EC%8B%AC-Use-Case
동영상 : https://youtu.be/zid-MVo7M-E?si=2zn_XdGzXujUzlpU
유즈케이스 관련 영상을 시청하고 든 생각입니다.
위쪽에서 정리해주신대로 유즈케이스가 기능별로 세분화되어 있는 게 좋은 것 같습니다. 그리고, 유즈케이스 네이밍을 동사로 시작하는 것도 좋은 명명법이라고 생각됩니다..!
다만, 유즈케이스를 주체가 되는 엔티티(Ex. Video 엔티티의 유즈케이스, User 엔티티의 유즈케이스)에 따라 분류하지 말고, 간단히 그 유즈케이스가 실행할 ’기능‘에 맞춰서 분류하고, 그 유즈케이스가 기능을 실행하기 위해 참고해야 하는 엔티티는 무엇인지 파악하는 편이 더 편리할 것 같습니다.
예시로,
ReadFollowerService : 내 팔로워를 조회하는 서비스
의 경우에,
유저 A가 자신의 팔로워를 조회할 수도 있고, 다른 유저 B의 팔로워를 조회해 볼 수도 있기 때문에, ’내 팔로워를 조회하는 서비스‘보다 ’유저의 팔로워를 조회하는 서비스‘로 정의하는 편이 편리할 것 같습니다.
특히 로그인/로그아웃 상태나 유저 정보에 영향을 받지 않는 기능들은 이렇게 broad하게 정리하는 게 편리할 듯 합니다.
반대로 UpdateMeService처럼 반드시 로그인 상태에서, ‘내’ 정보만 접속 가능해야 하는 유즈케이스들은 지금 정의를 유지해도 좋을 것 같습니다!
로그인 상태를 확인하는 요청을 하나의 기능을 가진 CheckLogin이라는 Usecase로 정의할 때 (실제로 이런 유즈케이스를 생성할 건 아니지만)
1)로그인이 필요한 요청 (Ex. UpdateMeService) UpdateMeService -> CheckLogin -> ~~
2)로그인이 필요없는 요청(Ex. View) ViewService -> ~~
이렇게 관리해도 괜찮을 것 같습니다. 그러면 서비스팀에서 저희가 개발 중에 특정 기능을 로그인 상태에서만 할 수 있도록 바꾼다거나, 아니면 전과 다른 엔티티들을 참고하도록 바꾼다거나 하는 식으로 기획이 달라져도 더 유연하게 대처할 수 있을 것 같아요.
. . .
MVI 부분과 관련해서, 아직 update 함수와 Intent 부분을 어떻게 관리해야 할지 조금 머리가 복잡한데…
우선 유저한테 직접 보이는 부분은 실제 엔티티가 아니라서, 적절히 updateContents 같은 usecase를 하나 만들어서 페이지 내용만 바꿔주면 될 것 같고… User나 Video처럼 엔티티를 직접적으로 바꾸는 유즈케이스들은 조금 더 찾아보겠습니다.
export default SomeUI (){
const { postData } = usePostView(postId)
const { isLoggedIn } = useAuthView()
return (
<div>
{ postData.isMine && <EditButton /> }
{ isLoggedIn && !postData.isMine && <LikeButton /> }
<CopyButton />
</div>
);
}
이렇게도 할 수 있지 않을까?
Just<PostDto> = {
data: PostDto
}
Async<Paginated<PostDto>>
Authed<PostDto> = {
data: PostDto
isAuthorized: true;
} | {
data: null
isAuthorized: false;
}
Maybe<PostDto>
공부하면서 느낀 거 적으려다 보니 PR 리뷰로는 좀 길어질 거 같아서 따로 이슈로 작성해 보겠습니다. 제가 맞게 이해하고 있는지, 혹시 잘못된 부분 있으면 코멘트 남겨주시면 감사하겠습니다.
우리의 목표
Clean Architecture와 MVI 패턴을 결합시키는 것. 현재 우리의 레포지토리는 Clean Architecture만 따르고 있습니다.
Clean Architecture 리뷰
Clean Architecture 자체는 Domain Layer-Application Layer-Adapter Layer로 이루어져 있으며, 우리는 이를 Entity-Usecase-(백엔드 서버와 통신하는) Usecase의 구현체(React Hook)로 대응시켰습니다.
사실 아직 불명확한 것은, Usecase의 구현체를 사용하는 UI 단위의 modules도 Adapter Layer에 포함되는가? 입니다만, Clean Architecture 안에서는 로직만 다룬다고 생각해 별개의 영역으로 생각했습니다.
User의 경우
UserAccessService
나CommentService
등이 존재하는데, 이들을LoginService
나GetCommentService
로 수정하는 것이 더 직관적이고 바람직해 보입니다.SigninService
: 회원가입을 위한 유즈케이스LoginService
: 로그인을 위한 유즈케이스SignoutService
: 회원 탈퇴를 위한 유즈케이스LogoutService
: 로그아웃을 위한 유즈케이스ReadMeService
: 내 유저 정보를 조회하는 유즈케이스 (마이페이지 등)UpdateMeService
: 내 유저 정보를 수정하는 유즈케이스ReadFollowerService
: 내 팔로워를 조회하는 유즈케이스ReadFollowingService
: 내 팔로잉을 조회하는 유즈케이스userAccessService
의 경우, 로그인과 로그아웃이 하나의 유즈케이스로 구현되어 있습니다. 유즈케이스를 구분하는 기준이 정확히 무엇일지 자문이 필요합니다..MVI와 어떻게 연결되는가?
MVI를 리액트 내에서 어떻게 구현해야 할까... 여기 Readme를 참고해 보았는데, 간단하게 정리하자면 이렇습니다.
model
은 (명사에 대한) 객체다. 이것은 Clean Architecture의 Entity와 잘 대응된다.view
는model
을 파라미터로 받고, DOM 구조를 리턴하는 함수다. (즉, 리액트 관점에서는 컴포넌트다)intent
는 (동사에 대한) 객체다. 즉, model에 대해 가능한 행위들의 모음이다.update
는model
과intent
를 파라미터로 받고, 새로운model
을 리턴하는 함수다.즉,
view
부분에서 이밴트핸들러 등으로 호출하는 것은intent
가 아니라intent
를 파라미터로 가지는update
라는 함수입니다. 요런 식으로요.이 구조를 참조해서, 저희 Clean Architecture에 적용을 한다면, 유즈케이스의 구현체인 리액트 훅은
model
(현재 우리 아키텍쳐 안에서는 DTO라고 생각됨)을 반환하는 함수 형태여야 할 것이고, 이 함수에 파라미터로 들어가는intent
는 다른 방식으로 정리가 되어야 하지않을까 하는데... 우선 여기까지만 생각해보았고 그렇다면 어떻게 정리할 것인지는 더 고민을 해봐야 할 것 같습니다.