Skip to content

KIMSEUNGWO/Room_Project

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

448 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

룸 프로젝트


제작 기간 & 참여 인원

  • 2024년 02월 02일 ~
  • 팀 프로젝트(2인)

배포주소

주소 : https://dagong.site


팀원소개

김승우 오승찬
@KIMSEUNGWOO @SEUNGCHAN
팀장 백엔드 백엔드
메인페이지, 마이페이지, 채팅방 구현 관리자페이지 구현

사용 기술

Back-end

  • Java 17 / Gradle
  • Oracle 11g
  • Apache Tomcat 9.0.78
  • Spring Boot 3.2.2
  • Git, Github
  • Thymeleaf 3.1.2
  • Hibernate 6.3.1 Final
  • QueryDSL 5.0.0
  • Apache Tomcat 9.0
  • KAKAO Login API
  • Cool SMS API

Front-end

  • HTML5
  • CSS3
  • Javascript

프로젝트 관리

노션 바로가기

노션 소개

노션 소개 펼쳐보기

> 워크플레이스

프로젝트의 스케쥴과 기능들을 담은 메인화면

> 기획 및 기능 (1/2)

프로젝트의 기획 및 기능을 정리해둔 문서목록

> 기획 및 기능 (2/2)

기획 및 기능에는 제한사항이 작성되어있다.

> 공통 API문서

공통 API문서가 작성되어있습니다. 객체 생성규칙, 반환 객체 정의 등

> API 문서

RestFul API 문서를 정리한 목록

> API 문서 상세

> 자료

프로젝트에 관한 자료나 공유해야하는 자료를 담은 자료실

> 자료상세

프로젝트 방향성

OOP(객체 지향 프로그래밍)

  • Getter, Setter 를 지양한다.
    • 모든 데이터는 객체 내부에서 처리하도록 한다. -> 캡슐화
  • Request, Response 데이터는 모두 객체화한다.
    • 필드값 변경시 수정사항 최소화, Collection 의존도 낮아짐
    • 각 객체는 용도에 따라 Request, Response 뒤에 변수명을 붙혀 용도를 명확히한다.
  • ResponseBody 반환객체는 ResponseEntity로 감싸고, 객체는 ResponseDto를 사용한다.
    • 응답객체는 ResponseDto를 상속받아 사용한다. ResponseDto 코드보기
    • 응답 데이터는 ResponseDto를 상속받은 ResponseObject를 사용한다. ResponseObject<T> 코드보기
    • Controller 반환타입 구현체 변경 시 변경범위 최소화, 새로운 객체를 무분별하게 추가하지 않아 코드복잡성 낮아짐.
  • 하위 Entity는 상위 Entity로부터 접근한다.
    • Member Entity 안에 Profile Entity가 있다면 Member -> Profile Entity 순서로 접근한다.
    • ex) member.hasProfile() -> (profile != null) profile.hasProfile() : false;
    • 코드 복잡성이 낮아진다, 무분별한 조건식을 작성할 가능성이 낮아진다, 예외 null처리가 간편해진다.
  • 변경 가능성 있는 class는 인터페이스화 한다. -> 다형성
    • ex) DB에 의존하는 Native SQL 이 존재하는 Repository는 인터페이스화 해서 Config에 직접 @Bean을 등록시킨다.

MVC 패턴

  • Controller는 최대한 코드가 없어야하고, 결과값을 출력하는 일만 한다.
  • Controller를 보고 무슨 일을 하는지 한눈에 파악할 수 있게 작성한다.
  • Service 로직은 오로지 Service 내부에서만 진행한다.
  • 메서드 내부에 메서드 들여쓰기를 지양한다.
    • ex) model.addAttribute("memberList", roomService.getResponseRoomMemberList(room, member)); -> 반환타입과 메서드의 일에 대해 파악하기 어려움
    • List<ResponseRoomMemberList> memberList = roomService.getResponseRoomMemberList(room, member); model.addAttribute("memberList", memberList); 반환타입과 변수명을 확인할 수 있도록 분리한다.

화면 구성

화면 구성 펼쳐보기

메인

메인화면 방생성
채팅방 나가기 로그인
  1. 방 리스트 화면 스크롤을 통한 Get API 호출, Jpa Pageable 활용해 Pagenation 구현 코드보기 search Method
  2. 검색조건 QueryDSL를 사용해 제목, 소개글, 태그내에서 검색 코드보기 search Method
  3. 카카오 로그인 API 적용 코드보기
  4. 로그인로직 디자인패턴 - 생성패턴 - Factory Method Pattern 적용 코드보기, 적용이유
  5. 아이디, 비밀번호 찾기 SMS API 적용 코드보기

관리자

이용중인 회원리스트 탈퇴한 회원리스트
현재 생성된 방 리스트 신고 리스트
신고내용 자세히 보기 신고당한 회원 정보 및 정지처리
  1. 구현내용 자유롭게 추가

채팅방

채팅방화면 설정변경
공지사항변경 방장권한
신고기능 비공개방 참여
  1. WebSocket 적용, 방 설정변경 -> MessageMapping 결과반환 코드보기 JAVA 코드보기 JS
  2. MessageType Enum으로 관리 코드보기
  3. 채팅방 접속 시 AccessToken 발급 코드보기
  4. 방장의 권한확인 코드 코드보기

마이페이지

마이페이지화면 휴대폰변경
비밀번호변경 계정삭제
  1. �개인정보수정, 비밀번호 변경(소셜회원 제외), 계정 삭제 로직 코드보기

화상회의(구현중)

화상채팅화면
  1. 구현중

프로젝트 결과

김승우

  • Notion을 통한 프로젝트 개발방향 공유, 협업 및 소통방법 습득 Notion 바로가기
    • 기획 및 기능 공유, API 문서, 예외클래스, 기타자료 등 프로젝트에 필요한 정보를 정리해두어서 상당히 유용했고, 차후 규모있는 프로젝트 진행 시 해당 템플릿을 사용할 예정임
    • 이번에 처음 적용해본 거라 자세히 기록하지 못했지만 다음 프로젝트에서는 Git 코드리뷰, 팀원간 의논한 내용을 정리하는 부분도 추가해 운영해볼 예정
  • ExceptionHandler 를 통한 전역예외처리 및 예외 상속을 통한 세분화 기술 습득 ExceptionHandler 코드보기
    • 예외 상속 객체가 증가할 수록 코드 복잡성 증가를 확인, 예외객체에 대한 중요성 인식
  • 사용자 권한획득 로직에 대해 ISP 원칙 적용 코드보기
  • 중첩클래스에 대한 이해도 증가
    • 한개의 Entity에 종속적이고, 다른 Entity와 상호작용이 없는 객체 다수 확인했고 이 객체들을 내부클래스로 변경 중첩클래스 코드보기
    • 코드 복잡성 낮아짐, Service 로직 간소화, Entity 외부클래스에 직접접근이 가능해 Getter, Setter 사용빈도 낮아짐, 외부로부터 정보은닉이 가능해짐
    • 내부클래스 static 클래스 사용한 이유 : 외부참조를 가져 메모리 사용량이 증가하고, GC 대상에서 제외되는 문제점이 존재해 static class로 사용
  • 커스텀 어노테이션의 장점 확인 @SessionLogin, @PathRoom 커스텀
    • SessionLoginArgumentResolver 코드보기
    • PathRoomArgumentResolver 코드보기
    • PathRoom은 기존의 PathVariable 을 기반으로 커스텀해 예외처리까지 가능하게 작성됨
    • 커스텀 어노테이션을 사용한 이유
      • 기존의 조건문을 하나로 통일하고 설정을 변경하여 여러 상황에 대응하도록 작성됨.
      • 따라서 기존 Controller에서 기본적으로 사용되던 조건문이 삭제되고 어노테이션 하나로 로직을 간소화할 수 있게되었음.
    • Interceptor를 사용하지 않은 이유
      • Interceptor를 사용하면 편리하지만 적용되는 범위를 Controller에서 확인할 수 없다는게 가장큰 단점이었음.
      • 또한 인터셉터가 증가할 수록 이후 service 로직에서 검증로직 방향을 잡기 어렵다는것을 확인함.
      • SessionLogin은 Interceptor로 적용해도 무방하나. PathRoom의 값을 검증하기 위해서는 PathVariable을 사용할 수 밖에 없었고, PathVariable에서 roomId를 가져와 실제 roomId가 존재하는지 검증하는 로직이 추가되는 것은 불가피 했기에 PathRoom 이라는 어노테이션을 직접 커스텀하게 되었음.
  • QueryDSL에 대한 이해도 증가
    • QueryDSL의 반환값을 Entity가 아닌 Projections를 활용해 Request객체로 반환하는 로직작성
    • Expression 변환 및 사용법 습득
    • 기존 Oracle -> MySQL 변경 시 QueryDSL 예외 발생하는 것을 확인.
      • 예외 발생 로직 -> QMember.member.eq(member) 각 객체간 비교시 예외발생 -> QMember.member.memberId.eq(member.memberId) 형식으로 실제 내부 값을 비교하는것으로 해결
    • JPA와 QueryDSL 속도 측정 결과 JPA가 20~30%정도의 유의미한 속도향상이 되는것을 확인. 이후 Pagenation이 필요한 데이터를 제외한 대부분의 코드는 JPA로 작성됨
  • Factory Method 패턴에 대한 이해도 상승 Validator 코드보기
    • 기존 Factory 내부에 Validator는 Interface였으나 공통로직을 다시 작성해야하는 오류를 발견
    • 따라서 abstract class로 변경하고 validLogin 메서드에 final 키워드를 넣어 Override가 불가능 하도록 변경.
    • 소셜회원과 기본회원은 예외관계까 다르기때문에 exception 반환처리는 상속시켜 하위클래스에서 정의하도록 변경.
    • 따라서 외부API(네이버, 구글 등등)가 추가될 경우 validator에서 해당 예외만 정의하도록 하여 클래스를 추가하기 쉽게 됨.
  • ArrayList의 initialCapacity 존재에 대한 이해증가

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors