서버를 기다리며, 서버 없이 개발하기 - Domain 설계 #101
shippingpark
started this conversation in
Idea
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
서론
안녕하세요! 3기 보노 입니다.
저희 팀은 총 일곱 번 기획을 엎는 결단을 거쳐 쇼케이스를 약 2주 앞두고
전쟁을 치르듯 기획, 디자인, 개발을 병행 중 입니다.
돌이켜 보니 급한 일정에 러너분들과 개발 이야기를 많이 나누지 못한 것 같아 아쉬움이 남습니다
그러니 페어 프로그래밍을 하듯
외부 데이터 없이도 도메인을 작성하고, 화면 작업을 수행하기 위해 하루동안 고민한 내용을 공유하고자 합니다.
#95 에 작성하였던 [구체적이지 않은 요구사항으로 개발하기- 확장성을 고려한 모델 설계]에 이어지는 글 입니다.
본문에 코드 분류, 계층 분류를 상징하는 단어가 자주 언급되지만 글이 너무 길어질 것 같아 자세히 설명하지 못했습니다.
저희 팀만의 해석이 담긴 단어들도 있어 가볍게 보시길 권장 드리고 싶습니다.
더불어 조언이 있다면 언제든 부탁드립니다!
+) 서비스를 잘 모르는 채 설명을 따라가기는 어려운 것 같습니다.
아래에 본문을 간단히 요약해 둡니다!
요약
모델 설계 이후 남은 도메인 설계(UseCase)를 진행
protocol로
UseCase가 1)필요로 하는 정보(Repository)와 2)제공해야 할 정보의 형태(UseCase)를 정의아직 서버가 없어 작성할 수 있는 명세가 없음, 테스트 편의 확보를 위해
Repository인터페이스를 채택한 구현체MockRepository를 만들어 서버 개발 진도에 발이 묶이지 않도록 처리핵심 기능이 되는
JudgmentUseCase(protocol)를 채택한JudgmentUseCaseMock구현체를 만들어Presentaion계층이Domain의 구현체를 모르도록 완전히 분리추후
Presentaion계층을도메인으로부터 Target 형태로 분리할 때 편의를 얻고자 목표+) 물리적 분리를 염두하는 이유는 UnitTest와 UITest 에서 빌드 시간 단축
감사합니다.
많은 조언 부탁드립니다.
좋은 하루 되세요!
모델 수정 진행
Bird는 '해외여행 시 지출 판단을 도와주는 기준'을 가진 서로 다른 모델을 의미합니다.지난 글에서는 앱의 핵심 모델인
Bird를 설계하는 과정을 설명했습니다.그렇게 작업을 진행하던 중 기획을 다듬고 있는
팀원의 질문을 받았습니다그럼요! 라고 대답했지만 뭔가 찜찜해서 코드를 다시 보았습니다
여러 생각이 떠올랐습니다. 생각나는 대로 정리해 보겠습니다
생각이 복잡해져서
Bird가 어떤 책임을 지고 있는지 천천히 다시 생각해 보았습니다Bird는 고유한 지출 판단 기준을 가지고 있으며 특정 방식으로 행동하도록 기대 받습니다.Bird는 구매 여부를 판단한 후 그 이유를 설명하는 역할 입니다이를 다시 정의하고 보니 기존의 작성한
Bird를지출판단책임 객체라 느낀 것과 달리지출 판단에 대한 결과를 상세 풀이하는 책임을 가졌음을 알게 되었습니다.화면에서 드러나는 지출판단은 'O' 뿐입니다.
그 외의 모든 것은 O, X가 결정된 이후 보다 자세하게 결정된 기능입니다.
따라서
지출판단은Bird이전에 존재해야 한다고 느끼고지출판단책임을 수행할 모델을 작성하였습니다.지출판단책임을 가진 Judgment 모델지출판단기준이 여러 개이기 때문에 그 자격을Judgment를 정의하고 이를 채택한 구현체를 생성하였습니다.예를 들어, 선택된 국가와 한국 내 평균을 기준으로 판단하는

좌측, 중간 새는
CountryAverageJudgment를 토대로 판정된 값에 살을 붙이는 친구일 것 입니다.우측 새는 기준 값으로 직전 소비를 평가하는 기준으로 생성된
PreviousJudgment에 살을 붙이는 친구로 보입니다.아직 정해지지 않은 기획단의 요구는 비워 두었습니다.
이제
Bird를 만들 차례입니다.Bird는 판단 결과에 근거를 추가하여 정보를 노출하는 역할로 보이기에,
어떤 정보가 보여져야 할 지를 고려하여 아래와 같이 작성하였습니다.
CountryAverageJudgment기준을 바탕으로 Bird의 행동을 구체화한ForignBird를 구현하였습니다이제 Bird 모델이
Judgment와 분리되며 각각의 역할이 명확해졌습니다또 지난 코드와 눈에 띄게 달라진 점은
명칭이기도 합니다.Judgment라는 앞선 모델의 역할과 책임을 분리하기 위해서Bird가 보여주는 다양한 정보나 행동�을BirdReaction, 즉Reaction이라 명명하였습니다.+)
BirdModel을 설명하니 뭔가 Model이라기 보다는ViewModel처럼 느껴 지기도 하는 것 같습니다.챗지피티에게 ViewModel의 정의를 물으니 더욱 비슷해 보입니다.
고민 끝에 폴더 분류를 아래와 같이 정리하였습니다.
(이를 지켜보던 팀원이 진짜
View-Model이네, 라는 말을 했습니다)도메인 설계 과정
저희 팀의 도메인은 UseCase, ViewModel(New!), Entity로 구성되었습니다.
UseCase는Presentation계층과Data계층의 중간에서 비즈니스 로직을 수행합니다.예를 들면,
화면의 요청을 토대로 (화면에 의한 UseCase 메서드 실행)데이터 계층에게 요청하여 필요한 정보를 받고 (Repository 메서드 실행 후 반환 값 획득)합니다.
1의 작업을 명시하기 위해 아래와 같이
JudgmentUseCase를 정의하였습니다.해당 인터페이스는 Presentaion 계층에서 필요로 하는
UseCase의 역할이 됩니다. (호출자가 Presentaion/View)위의 메서드는 사용자에 의해 발생되는 이벤트를 알고 있는(
Presentaion)의 필요에 의해 실행될 것 입니다.이제
UseCase는 위의 몇몇 메서드 정의 시적절한 return 값을 만들기 위해서 데이터 계층을 필요로 하게 될 것 입니다.
UseCase가 필요로하는 정보를 관리할 객체의 책임을 아래와 같이 두 개로 분류하였습니다.이제 간 계층 간의 전환이 어떤 식으로 이루어질 지 대략적인 감을 잡게 되었습니다 !
계층 간의 소통 방식이 정해졌으니 이제 위의 메서드를 정의할 구현체가 필요합니다.
데이터 전달 구현체 없이 개발하기
서버 개발이 완료되지 않았으므로 Mock 데이터를 사용해 개발을 진행하였습니다.
아래 코드처럼 원하는 값의 형태를 조작하여
RepositoryMock구현체를 작성하였습니다�
Presentaion계층, 즉View가 사용할UseCase또한 Mock으로 작성합니다.아주 엄밀히 고려하며 진행하지 않았기 때문에 느낌만 확인하시면 좋을 것 같습니다!
여담
저는 본래 이전 프로젝트에서 Domain -> Data (고->저)가 아닌
Presentaion -> Domain 구간(저->고)에는 인터페이스를 두지 않는 편이었습니다.
하지만 해당 프로젝트는 UnitTest와 UITest를 진행하고 있고 빠른 빌드를 위해
추후 View와 Domain 코드를 물리적으로 분리할 목적으로 UseCase를 추상화하였습니다.
당장은 ViewController에서 Preview를 사용할 때 실제 구현체를 사용하지 않기 위함 입니다.
Mock 끼리는 의존성을 분리할 필요를 느끼기 어려워
UseCaseMock 내부에서 RepositoryMock 값을 직접 생성되도록 작성하였습니다.
결론
이렇게
UseCase설계를 마무리 지었습니다.내일은 UnitTest를 거쳐 코드를 다듬고 데이터를 기다리며 화면 작업을 할 예정입니다.
어쩌다 밤을 새버려서 글이 두서가 없습니다 ㅜㅜ 이상하게 서술된 점이 있다면 댓글을 부탁 드립니다.
또 두서 없이 써 내린 글이지만 많은 조언 부탁드립니다!
감사합니다.
Beta Was this translation helpful? Give feedback.
All reactions