1. 주제 선정 및 프로젝트 일정
프로젝트 일정 : 4월 25일 ~ 5월 7일
개발 툴 : JAVA, IntelliJ, Git
실제 시간과 연동하여 간단한 티켓팅 프로그램을 만들면 재밌겠다는 의견이 모여
인*파크 등 티켓팅에 대해 자바만으로 간단한 구현을 해봤다.
회원 및 회원의 예매내역에 대해서는 DB를 사용하지 않기 때문에
파일에 저장하고 불러오는 방식을 선택했다. (ObjectInputStream...)
2. 담당 기능 및 구조
- Member : 회원 한 명에 대한 클래스. 개인정보, 예매내역(List)를 각각 저장
- MemberRepository : 회원정보를 저장. DB 대신 사용하며 회원 관련한 CRUD 관리하는 역할.
→ DB 일관성에서 착안하여 싱글톤 패턴으로 구현
로그인
1️⃣ 로그인
이메일 입력 : 형식 및 가입 여부 검증
비밀번호 입력 : 일치 → 로그인 성공, 마이페이지로 이동
3회 이상 불일치 → 로그인 잠금(30초)

이메일·비밀번호 찾기
3️⃣ 아이디 찾기
휴대폰 번호 입력: 랜덤 생성되는 인증코드 6자리로 본인인증
코드 일치 → 이메일 출력
코드 불일치 → 재입력 / 코드 새로 받기 / 뒤로가기
4️⃣ 비번 찾기
이메일 입력: 회원 가입 및 일치 여부 검증
휴대폰 번호 입력 : 인증코드 메서드 재사용, 비밀번호 출력

마이페이지
- 메인메뉴에서 로그인 및 회원가입 대신 마이페이지로 연결
- 로그인한 회원의 정보를 출력
→ MyPageView 생성자의 매개변수로 로그인한 Member(인스턴스)를 사용
1️⃣ 비밀번호 변경
로그인 회원의 기존 비밀번호와 일치 → 새로운 비밀번호로 수정 가능
3️⃣ 예매내역
로그인 회원의 예매내역 조회 및 취소
- 예매내역 없음 : ‘예매내역이 없습니다’ 출력
- 예매내역 있음 :
- 예매한 공연 날짜순으로 내림차 정렬 후 출력 (ticketList, stream.sorted)
- 조회 목록의 번호를 입력하여 예매내역 취소 가능

4️⃣ 로그아웃
- MemberRepository loginMember 필드를 null로 재할당
- 메인 메뉴에서 loginMember가 null인지 조건문으로 확인하여 다시 로그인 및 회원가입을 연결


3. 트러블 슈팅
3-1. 파일 경로
Member 관련해서 다루면서 파일 관리가 가장 생소했고 까다로웠다.
OS도 Windows, Mac 다르고 디렉토리도 모두 다르기 때문에
현재 작업 디렉토리를 기준으로 경로를 찾을 수 있도록 System.getProperty(“user.dir”) 를 사용했다.


3-2. 직렬화 / 역직렬화
java.io.InvalidClassException:local class incompatible
→ serialVersionUID 사용
로그인 비밀번호 3회 불일치 시 30초 동안 계정잠금 기능을 추가로 개발하면서
Member에 loginEnabled, lastDisabledTime 필드를 추가하게 됐다.
implements Serializable은 잘 적용되고 있었는데 실행해보니 오류가 발생했다.
에러 메세지를 구글링한 결과
필드나 메서드 등 클래스 멤버에 변경사항이 발생하면 파일 버전이 달라지면서
JVM이 자동으로 부여하던 serialVersionUID가 갱신되고,
역직렬화 시 기존의 serialVesrionUID와 달라서 Exception이 발생한 것이었다.
따라서 명시적으로 serialVersionUID를 static final로 지정해 해결했다.
다음부터는 implements Serializable 작성 시 처음부터 serialVersionUID를 설정해야함을 알 수 있었다.
소감
이번 프로젝트를 통해 MVC 패턴을 완벽하지는 않지만 클래스를 나눠서 개발하면서 싱글톤 패턴이나 의존성 주입을 적용하는 등 객체지향 프로그래밍의 장점을 몸소 겪을 수 있었다.
다만 각자 개발은 큰 문제없이 진행됐는데 결과물을 연결하는 순간 다양한 에러가 발생했기에 그만큼 배워야할 부분이 많구나 절실히 느꼈다.
초기 기획을 꼼꼼히 했다면 발생하지 않았을 에러들도 있었고
자바에 대해 잊고 있던 부분에서 문제가 발생하기도 했다.
다른 팀원이 사용한 sc.next()로 인해 내가 맡은 부분(sc.nextLine()으로 처리)에서
입력하지 않았는데도 엔터가 입력되는 현상이 발생했는데
sc.next() 와 sc.nextLine()의 차이점인 개행문자 여부를 잊고 있는 바람에
내 코드가 문제인 줄 알고 한 시간을 허비하기도 했다.
그래도 지난 프로젝트 보다 전체적인 구조를 의논도 하고
다른 팀원들의 질문을 같이 고민하면서
활발하게 소통을 했기 때문에 협업 다운 팀프로젝트를 경험할 수 있어서 좋았다.
파일 경로
System.getProp직렬화 / 역직렬화
java.io.InvalidClassException:
local class incompatible
→ serialVersionUIDerty(“user.dir”)