은행 기능 만들기 팀 프로젝트(1일차)

HYEMIN LEE·2022년 11월 24일
0

팀프로젝트

목록 보기
2/2
post-custom-banner

오늘부터 본격 프로젝트가 들어간 날, 팀원은 저번과 같으니 적지 않는다. 다음주 화요일까지 은행 프로그램이나 호텔예약 프로그램 중 하나를 선택해 만들어서 발표하는 거였는데 나는 호텔 사이즈나 재고? 이런거 일일이 설정하기 귀찮다고 은행을 골랐고 다른 분들도 직관적으로 보기에 명세가 분명하다고 은행을 많이 골라 은행 프로그램을 만들기로 했다.

처음에는 요구사항에 대한 아이디어 메모를 먼저 했다. 이후에 필요한 기능을 구분했고 유저정보, 계좌정보, 거래내역정보 이렇게 3개로 데이터베이스를 나누기로 했는데 우리가 토론을 하면서 어떤 생각인지 제대로 설명을 못 한 탓에 관호님이 오해를 하셔서 우리가 코드 중심으로 생각을 너무 이어나갔다고 하셔서 하나로 만들기로 하고 계좌도 하나만 만들어진다는 가정으로 코드를 구현하기로 했다.

원래는 이름을 기준으로 검색을 하고 계좌를 만들고 삭제를 하는 것이었는데 동명이인이 있는 경우와 은행과 고객의 역할을 나눠야한다는 생각에 로그인 기능을 만들기로 했다.

Admin과 고객의 로그인을 한 후의 UI 와 Logic을 분리해놓는 틀은 관호님이 짜주셨다.

관호님이 계층적으로 개발을 하는 법에 대해 강조를 많이 하시면서 프로젝트를 처음부터 그렇게 만들어주신데다 UI 부분을 미리 짜오셔서 그걸 보면서 로직을 짜면 되서 제법 편했다.

처음에는 회원가입을 하는 로직을 짰고 학윤님로그인을 하는 기능을 짰고 회원 Entity동균님UserDB성현님이 짜셨는데 전부 한 후 관호님이 보시면서 나누신게 저 Admin과 일반 User 사이의 로직 분리였다.

또한 UI와 Logic을 아직 잘 구분하지 못한 나와 학윤님이 함수 하나에서 검증과 출력을 전부 한 것을 어떻게 분리해야하는지 설명하시면서 appUIUILogicLogicdb를 바라보고 값을 자신을 바라보는 쪽에 반환해준다는 것을 알려주셔서 감을 잡을 수 있었다.

그러고 나서 다시 역할을 분할해 나 같은 경우에는 관리자 로직을 구현했는데 처음에 유저 정보 수정이 명세에 있어 이걸 어떤 식으로 하지 팀원들과 상의를 하다가 그냥 하나하나 다 넣자로 갔는데 로직과 UI를 구분해서 짜다보니 case가 너무 많아져서 다른 팀을 도우러 가신 관호님을 불러 비밀번호 하나만 바꾸는 기능으로 줄이기로 했다.

사용자 정보 삭제는 성현님이 짜신 UserDB에 delete를 하는 함수를 하나 만들어 넣었고 계좌번호로 사용자 찾기는 계좌 번호를 받아와 일치하는 걸 삭제하는 걸로 짰다. 소유자명으로 계좌찾기의 경우에는 우리는 저걸 id값으로 대체하기로 해서 id를 받아와 계좌를 찾는 로직으로 만들었다.

학윤님과 성현님의 경우에는 학윤님이 우리팀에서 학습 진도가 가장 느리셔서 성현님이 함께 붙어 User 로직을 짜기로 했고 동균님User entity에서 Account를 랜덤값으로 받아서 할 수 없는지 고민을 하시고 넣으셨다. 관호님은 그 사이 다른 팀에 지원을 가셨다.

그러다가 중간에 어느 정도 구현이 끝났으니 다 push, pull을 해 맞추고 이제 branch를 사용해보자는 관호님의 의견에 main에서만 구현을 하던 우리가 드디어 develop 브런치로 옮기고 그 안에서 feat/맡은기능 으로 나누어 merge를 해보기로 했다.

아침에 내거 인텔리제이가 pull을 했는데 out 디렉터리를 안 만들어서 한 시간 넘게 그걸 붙잡고 있었던 탓에 저렇게 브런치를 나눴을 때는 어느새 점심시간이어서 밥을 먹고 와서 다시 하기로 했다. 그러다 거래내역을 저장하는 걸로 서로 주장하는 게 갈렸고 한참을 토론했다. 나는 DB랑 entity를 아예 나누자는 입장이었고 다른 분은 결국 거래 내역도 유저가 관리하는거니 그 안에 배열로 넣자는 입장이신데다 관호님은 우리가 고민을 많이 했으면 좋겠다고 이번 건 말 안 하시겠다 하셔서 한참 토론을 하다 튜터님께 8조 전체가 시위하러 갔다.

그래서 객체에는 배열 사용을 최대한 지양하는게 좋다는 걸 알았다. 또한 UserDB에 거래 내역을 넣으면 그 친구는 로그인도 책임져야하고 계좌 생성과 삭제도 책임쳐야하고 거래에 대한 책임도 져야해서 하지 않는게 좋다고 하셨다. 단일책임원칙 때문에 그런건가 여쭸더니 그게 맞다고 하셨다.

이후에 튜너님과 대화를 나누다가 관호님이 자신이 오해를 한 것을 깨달으셔서 우리가 처음에 계획했던 방향으로 가기로 했고 놀랍게도 그 때가 벌써 저녁이었다. 저녁을 먹기로 한 사이에 또 배가 안 고팠던 탓에 개인적으로 우리 팀의 속도가 상당히 빠르다고 생각했고 개선하고 싶은 점이 있어 정리를 했고 그 내용은 아래와 같다.

앱 구동 수정 및 구현 요청사항

App

  • 로그인 통합

관리자인지 회원인지 구분할 거 없이 한 로그인창으로 로그인 관리자인가 아닌가 구분해주는 것을 구현해서 관리자면 관리자 UI로 유저면 유저 UI로 이동         

접근 권한은 UserDB에만 있기 때문에 처리해줄 중간 로직 필요
//사실 가장 이상적인 건 로그인 DB가 따로 있어 App에서 수행되는 로직은 여기에만 접근가능하게 하는 것이 보안에도 좋음

UserUI

  • 계좌 추가 생성

UserDB와 AccountDB의 연결을 위해 계좌 생성 시 Max + 1값을 계좌로 User.getUserID()를 아이디 값으로 연결        

로그인을 한 순간부터 User 객체를 검증받은 것이기 때문에 계속 가지고 있으면 계좌추가는 for문 돌릴 필요 없음  

AdminLogic으로 요청해야함       

권한은 UserDB 제한 그 외 필요한 사항은 로직단에서 AdminLogic에 키값 or User 정보를 넘겨서 처리 받는다

  • 계좌 삭제 추가

    유저가 원해서 삭제하는거지 관리자가 멋대로 삭제할 수 없기 때문

AdminLogic

  • 회원 정보 변경 사항 변경

개명의 이유나 비밀번호를 잊은 이유 등으로 변경 사항 발생 고려

  • 관리자 추가 기능 구현

사용자의 정보 수정 및 삭제는 사용자의 요청에 따라 사용자Logic에서 처리가 되기 때문에 사용자 계좌 관리 기능은 불필요함

  • 계좌번호로 사용자 찾기

은행에서 직접 입출금을 해주는 경우를 고려    

소유자명으로 계좌찾기 삭제 로그인 시점에 이미 구현된데다 은행은 소유자명으로 계좌를 찾을 이유가 없음

  • 은행 내 한 달 정보 조회

    은행 실적 관련 문제로 신규 가입이나 거래내역 조회 추가

  • 삭제를 유저 UI에서 받아와 구현하는 이유

    계좌번호는 유저가 삭제를 요청해야지 관리자라고 해서 함부로 삭제해서는 안 된다.

ex) UI 삭제 선택 → Logic 삭제 로직(AdminLogic에 일을 해줄 것을 요청) → AdminLogic 요청을 받아서 디비에 접근해서 기능을 수행 결과 던져주기 → Logic 결과 받아서 UI로 출력

나와 마찬가지로 가볍게 기능들을 그림으로 그려오신 분이 계셨는데 그 분은 일단 명세에 따르는 것이 중요하고 그 기능을 구현하는 것이 최우선이기 때문에 이렇게 하자 하셨고 나는 그래도 취업을 준비하는 캠프고 만드는 프로젝트 하나하나 제대로 만들고 싶다. 는 입장이었다.

내가 글을 잘 못 적은 탓인지 다른 분은 내게 설명을 해달라하셨고 관호님은 여전히 침묵 중이셨다. 예시를 삭제로 들어서인지 DB 접근 권한을 나누고 싶어서 저렇게 했다가 저 로직이 이미 User에게 접근 권한을 준 것 아니냐 검증할 수 있는 것도 없이 저렇게 하면 지금이랑 뭐가 다르냐고 하셔서 검증은 Admin 로직에서 한다고 설명했다.

그러다 의견이 합쳐지지 않아 다른 튜터님을 찾아갔는데 객체간의 협력에 익숙해지라고 하는 프로젝트이니 너무 복잡하게 하지 말고 그냥 관리자에게 그런 권한이 있다는 전재를 깔고 가도 된다고 하셨다. 흙...

다른 분들이 그래서 나중에 시간이 남으면 fork 해서 고치면 되니까 너무 상심하지 말라고 하셨고 나는 오히려 내가 너무 욕심이 많아서 죄송하다고 사과했다.

그렇게 정리를 하고 거래내역DB와 계좌 DB 그리고 각 엔터티들을 어떻게 짤 것인지 서로 나누다가 관호님이 UI단 정리하면서 변경된 로직같은 거 바꾸기로 하시고 나와 동균님이 거래내역을, 학윤님과 성현님이 계좌를 담당해서 2인 1조로 짜기로 했다.

나와 동균님은 거래내역 엔터티가 생성될 때 일자와 시간을 분리하는 방법을 찾다가 Date는 이제 안 쓰는게 좋고 LocalDateLocalTime을 쓰는게 좋다는 걸 알았다. 또한 사용법도 Date와는 달라서 Datenew Date()를 해주었지만 저 둘은 그냥 .now()를 하면 현재 날짜 혹은 시간이 찍히더라. 만약 저체를 다 찍고 싶다 하면 LocalDateTime을 쓰면 된다는 것도 알았다.

어제 만든 메모장 프로그램에 대한 서면 피드백을 튜터님이 주셨는데 거기에 객체가 비어있다고 return null은 하지 않는 것이 좋다고 하시며 블로그 하나를 추천해주셨다. Optional<T>에 관한 내용이 있는 블로그였는데 예를 들어 객체 안에서 객체를 불러오는 경우 앞의 객체가 null이라면 오류가 나는 식으로 객체를 null 값으로 return 해주는 것은 오류가 날 확률이 높아 사용을 지양하고 Optional<T>를 쓰라는 것이었다.

마침 서로 화면공유를 하면서 의견을 주고 받는다지만 엔터티를 내가 다 짜고 거래내역 DB를 동균님이 짜기로 하셔서 그걸 알려드렸다. 거래내역 DB는 정말 생각보다 별거 없어서 9시가 되기도 한 20분 정도 전이고 성현님 쪽도 아직 끝나지 않아서 동균님이 질문하시는 걸 답해주다가 <>를 궁금해하셔서 찾아보니 저 안에 객체만 들어간다는 걸 알았다. 그래서 첫주차 때 스트림이 이해가 가지 않아 튜터님께 여쭤봤을 때 어떤 객체일지 모를 때 Object를 쓴다고 하신 걸 떠올려서 찾아보니 저 Object가 모든 객체의 최상위 클래스란다. 또 하나 배웠다.

마지막으로 성현님이 계좌번호에 동균님이 짜셨던 걸 가져와 정규표현식으로 다시 만들어서 넣으신 후 뭔가 물어보러 오셨는데 그건 까먹었고 우린 다했고 곧 9시 이니 모여서 정리를 한 번 하자고 했다.

그리고 git을 쓰고부터 오늘 오후 내내 조마조마했던 시간이 돌아왔다. 관호님이 내가 짠거에서 유용하다 판단하신 것만 뽑아와서 App단과 UI쪽과 Logic의 일부를 싹 갈아엎어버리셔서 충돌이 나서 전부 날릴까봐 두려워하셔서 변경 사항이 가장 큰 관호님 먼저 merge를 하자고 했다. 다행히 충돌은 없었고 뒤이어 merge한 나와 동균님이 만든 거래내역 역시 관호님이 안 건드리신 부분이라 큰 문제가 없었다. 문제는 관호님이 필요에 의해 조금 손을 보신 계좌 쪽이었는데 성현님이 그건 내일 리뷰하고 안전한 곳에 fork를 해놓은 후 합치자고 제안하셨다.

전부 하자 9시여서 남을 사람은 남고 이만 쉬러갈 사람은 쉬러 가기로 했는데 성현님과 학윤님은 아직 못다한 구현을 둘이서 조용한 곳에서 하자고 이동하셨고 아직 반에 계신 분들과 낯을 가려서 나는 그냥 혼자 좀 변경하다가 쉬겠다고 하고 zep을 나왔다.

그 후 이 일지를 쓰면서 쉴 겸 로직단에서 변경할게 보이는대로 수정 중인데 내일 merge할 때 사고나는 건 아니겠지;;

관호님이 내일은 fork를 하는 김에 pull request까지 해보자고 하셨다.

내일은 또 어떤 사고가 날까 조마조마하지만 기대되고 재밌는 나날이다. 다만 여기에 재미를 들여서 밥을 잘 안 먹어 부모님이 걱정하시니 자제는 좀 필요할 듯

profile
개발자의 길에 한 걸음 더
post-custom-banner

0개의 댓글