클래스이름@16진수로_표시된_해시코드
형태의 문자열을 반환public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
public String toString() {
return String.format("# 이름: %s, 이메일: %s, 나이: %d세, 성별: %s, 가입일: %s"
, this.memberName, this.email, this.age, this.gender, this.regDate);
}
package day06.member;
import java.time.LocalDate;
// 역할: 회원정보 1개를 가지고 있어야 한다.
public class Member {
int id; // 식별변호
String email;
String memberName;
String password;
String gender;
int age;
LocalDate regDate; // 회원가입일자
// 생성자: 회원정보가 생성될 때 초기 데이터를 처리
// -> 객체가 생성될 시점에 호출되는 함수로 객체의 초기화를 담당한다.
// 시스템이 생성하는 데이터: 회원번호, 회원가입일자
// 사용자가 제공하는 데이터: 이메일, 패스워드, 이름, 성별, 나이
// 사용자가 제공해야하는 것은 생성자의 파라미터로 외부에서 입력하게 만듦
Member(String email, String password, String memberName, String gender, int age) {
this.id = 1;
this.regDate = LocalDate.now(); // 현재 시간을 읽어서 처리
this.email = email;
this.password = password;
this.memberName = memberName;
this.gender = gender;
this.age = age;
}
// toString: 객체의 정보를 출력할 수 있음 (자동호출되므로 따로 호출 필요 X)
public String toString() {
return String.format("# 이름: %s, 이메일: %s, 나이: %d세, 성별: %s, 가입일: %s"
, this.memberName, this.email, this.age, this.gender, this.regDate);
}
// 회원의 비밀번호를 수정하는 메서드
void changePassword(String newPassword) {
this.password = newPassword;
}
}
package day06.member;
// 역할: MemberRepository에서 배열필드를 정의하지않고 이 곳에 정의하여 가독성과 유지보수성을 올림
// 또한 배열을 다루는 다양한 메서드도 정의해놓았기 때문에
// MemberRepository에서 간단하게 사용가능!
public class MemberList {
Member[] mArr;
MemberList() {
this.mArr = new Member[0]; // 빈 배열
}
// 맨 끝에 추가
void push(Member newMember) {
Member[] temp = new Member[mArr.length + 1];
for (int i = 0; i < mArr.length; i++) {
temp[i] = mArr[i];
}
temp[temp.length - 1] = newMember;
mArr = temp;
}
// 인덱스 찾기
int findIndex(String email) {
for (int i = 0; i < mArr.length; i++) {
if (email.equals(mArr[i].email)) {
return i;
}
}
return -1;
}
// 한 명의 회원 정보 얻기
Member get(String email) {
int index = findIndex(email);
return get(index);
}
Member get(int index) {
return mArr[index];
}
// 맨 끝 제거
Member pop() {
// 맨 끝 회원 백업
Member lastMember = mArr[mArr.length - 1];
Member[] temp = new Member[mArr.length - 1];
for (int i = 0; i < temp.length; i++) {
temp[i] = mArr[i];
}
mArr = temp;
return lastMember;
}
// 회원 정보 삭제
Member remove(int index) {
// 삭제 대상 백업
Member removedMember = mArr[index];
for (int i = index; i < mArr.length - 1; i++) {
mArr[i] = mArr[i + 1];
}
pop();
return removedMember;
}
Member remove(Member deleteMember) {
int index = findIndex(deleteMember.email);
return remove(index);
}
// 배열에 저장된 요소 수 리턴
int size() {
return mArr.length;
}
// 배열 리턴
Member[] getMembers() {
return mArr;
}
}
package day06.member;
// 역할: 회원 배열을 관리하는 역할 - 회원 데이터 저장소
public class MemberRepository {
// 필드
// static Member[] members; // 현재 관리되는 회원 배열
// static Member[] restoreList; // 삭제된 회원들이 모일 배열
MemberList members;
MemberList restoreList;
// 생성자
MemberRepository() {
// this.members = new Member[3];
// members[0] = new Member("abc@def.com", "1234", "콩순이", "여성", 50);
// members[1] = new Member("ghi@def.com", "5432", "팥돌이", "남성", 40);
// members[2] = new Member("xyz@def.com", "7890", "팥죽이", "여성", 30);
this.members = new MemberList();
// push의 파라미터로 Member타입의 `객체`가 들어올 수 있기 때문에 Member클래스에서 만들었던 생성자가 들어갈 수 있음 (생성자는 객체 생성 역할 이기 때문에)
members.push(new Member("abc@def.com", "1234", "콩순이", "여성", 50));
members.push(new Member("ghi@def.com", "5432", "팥돌이", "남성", 40));
members.push(new Member("xyz@def.com", "7890", "팥죽이", "여성", 30));
this.restoreList = new MemberList();
}
// 메서드
/**
* 생성된 회원정보를 회원 배열에 끝에 추가하는 기능
* @param newMember - 사용자의 입력으로 전달된 회원 정보 객체
*/
void addNewMember(Member newMember) {
// 배열에 데이터를 추가하는 로직
// Member[] temp = new Member[members.length + 1];
// for (int i = 0; i < members.length; i++) {
// temp[i] = members[i];
// }
// temp[temp.length - 1] = newMember;
// members = temp;
members.push(newMember);
}
/**
* 이메일 중복을 확인하는 기능
* @param targetEmail - 검사할 사용자의 입력 이메일 값
* @return - 이메일이 이미 존재한다면 true,
* 존재하지 않는 사용가능한 이메일이면 false
* @author - 코딩킹
* @since 2024.04.16
*/
boolean isDuplicateEmail(String targetEmail) {
// 이메일을 통해 회원을 찾았다면 이미 존재한다는 것이므로 (= 중복) true
return findMemberByEmail(targetEmail) != null;
}
/**
* 이메일을 통해 회원의 모든 정보(객체)를 가져오는 메서드
* @param inputEmail - 사용자가 입력한 이메일값
* @return - 해당 이메일을 통해 찾아낸 회원 객체,
* 만약 찾지 못하면 null을 리턴
*/
public Member findMemberByEmail(String inputEmail) {
// for (Member m : members) {
// if (inputEmail.equals(m.email)) {
// return m;
// }
// }
// return null;
return members.get(inputEmail);
}
// int findIndex(String email) {
// for (int i = 0; i < members.length; i++) {
// if (email.equals(members[i].email)) {
// return i;
// }
// }
// return -1;
// }
// 배열에서 회원정보 삭제 (복구 리스트에 담기)
public void removeMember(String inputEmail) {
// int index = findIndex(inputEmail);
int index = members.findIndex(inputEmail);
if (index == -1) return;
// for (int i = index; i < members.length - 1; i++) {
// members[i] = members[i + 1];
// }
//
// Member[] temp = new Member[members.length - 1];
// for (int i = 0; i < temp.length; i++) {
// temp[i] = members[i];
// }
// members = temp;
Member deletedMember = members.remove(index);
restoreList.push(deletedMember);
}
}
package day06.member;
import day06.util.SimpleInput;
// 역할: 회원 데이터 관리를 위해 "입력 출력"을 담당함
public class MemberView {
// 객체의 협력
MemberRepository mr;
SimpleInput si;
MemberView() {
this.mr = new MemberRepository();
this.si = new SimpleInput();
}
void showMembers() {
System.out.printf("========= 현재 회원 목록 (총 %d명) ==========\n", mr.members.size());
for (Member m : mr.members.getMembers()) {
System.out.println(m);
}
}
// 회원정보 생성을 위해 입력을 처리
void inputNewMember() {
String email = null;
while (true) {
email = si.input("- 이메일: ");
// 이메일이 중복되는지 확인
// 중복되지 않는 이메일이라면 while문 탈출
if (!mr.isDuplicateEmail(email)) {
break;
}
System.out.println("중복된 이메일입니다.");
}
String name = si.input("- 이름: ");
String password = si.input("- 패스워드: ");
String gender = si.input("- 성별: ");
int age = Integer.parseInt(si.input("- 나이: "));
// 입력데이터를 기반으로 한명의 회원 객체를 생성
Member newMember = new Member(email, password, name, gender, age);
// 위임 - 관심사의 분리
mr.addNewMember(newMember);
}
// 사용자에게 보여줄 전체 메뉴 화면 출력
String showProgramMenu() {
System.out.println("\n##### 회원 관리 시스템 #####");
System.out.println("* 1. 회원 정보 등록하기");
System.out.println("* 2. 개별회원 정보 조회하기");
System.out.println("* 3. 전체회원 정보 조회하기");
System.out.println("* 4. 회원 정보 수정하기");
System.out.println("* 5. 회원 탈퇴하기");
System.out.println("* 6. 회원 복구하기");
System.out.println("* 7. 프로그램 종료");
System.out.println("=============================");
String menuNumber = si.input("- 메뉴 번호: ");
return menuNumber;
}
// 프로그램 종료를 판단하는 입출력
boolean exitProgram() {
String exit = si.input("- 프로그램을 종료합니까? [y/n]\n>> ");
if (exit.equals("y")) {
System.out.println("프로그램을 종료합니다!");
return true;
}
else {
System.out.println("프로그램 종료를 취소합니다.");
return false;
}
}
// 이메일 입력받고 찾은 회원정보를 출력
public void getMember() {
String inputEmail = si.input("# 조회하실 회원의 이메일을 입력하세요.\n>> ");
// 이메일이 일치하는 회원이 있는지 조회
Member foundMember = mr.findMemberByEmail(inputEmail);
if (foundMember != null) {
System.out.println("============= 조회 결과 ============");
System.out.println("# 이름: " + foundMember.memberName);
System.out.println("# 비밀번호: " + foundMember.password);
System.out.println("# 성별: " + foundMember.gender);
System.out.println("# 나이: " + foundMember.age);
System.out.println();
} else {
System.out.println("\n# 해당 회원은 존재하지 않습니다.");
}
}
// 수정 대상의 이메일을 입력받고 조회에 성공하면 패스워드를 수정
public void updatePassword() {
String inputEmail = si.input("# 수정하실 회원의 이메일을 입력하세요.\n>> ");
// 이메일이 일치하는 회원이 있는지 조회
Member foundMember = mr.findMemberByEmail(inputEmail);
if (foundMember != null) {
// 기존 비밀번호를 입력해주세요
// 비번 수정
System.out.printf("# %s님의 비밀번호를 변경합니다.\n", foundMember.memberName);
String newPassword = si.input("# 새 비밀번호: ");
// 회원정보 실제로 수정
// foundMember.password = newPassword;
foundMember.changePassword(newPassword);
System.out.println("# 비밀번호 변경이 완료되었습니다.");
} else {
System.out.println("\n# 해당 회원은 존재하지 않습니다.");
}
}
public void deleteMember() {
String inputEmail = si.input("# 삭제하실 회원의 이메일을 입력하세요.\n>> ");
// 이메일이 일치하는 회원이 있는지 조회
Member foundMember = mr.findMemberByEmail(inputEmail);
if (foundMember != null) {
// 삭제 진행
// 패스워드 검사
String inputPw = si.input("# 비밀번호를 입력: ");
if (inputPw.equals(foundMember.password)) {
mr.removeMember(inputEmail);
System.out.println("# 회원 탈퇴가 처리되었습니다. 복구하시려면 복구메뉴를 이용하세요.");
} else {
System.out.println("\n# 비밀번호가 일치하지 않습니다. 탈퇴를 취소합니다.");
}
} else {
System.out.println("\n# 해당 회원은 존재하지 않습니다.");
}
}
}
package day06.member;
import day06.util.SimpleInput;
// 역할: 사용자의 메뉴 입력을 분기하는 역할
public class MemberController {
MemberView mv;
SimpleInput si;
MemberController() {
this.mv = new MemberView();
this.si = new SimpleInput();
}
// 메뉴 입력 분기에 따라 할 일을 나눠주는 기능
void run() {
while (true) {
String menuNum = mv.showProgramMenu();
switch (menuNum) {
case "1":
mv.inputNewMember();
break;
case "2":
// 이메일을 입력받아서 회원을 개별조회 해주는 코드
mv.getMember();
break;
case "3":
mv.showMembers();
break;
case "4":
mv.updatePassword();
break;
case "5":
mv.deleteMember();
break;
case "6":
// mv.restoreMember();
break;
case "7":
boolean flag = mv.exitProgram();
if (flag) return; // true면 종료
} // end switch
si.stopInput();
} // end while
}
}
package day06.util;
import java.util.Scanner;
// 역할: 스캐너 입력을 간소화해주는 객체
public class SimpleInput {
Scanner sc = new Scanner(System.in);
// 문자열 입력을 처리
public String input(String message) {
System.out.print(message);
return sc.nextLine();
}
// 엔터를 누르기 전까지 멈춰 있는 기능
public void stopInput() {
System.out.println("\n=========== 엔터를 누르면 계속 … ============");
sc.nextLine();
}
}
package day06.member;
import day06.util.SimpleInput;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
MemberController mc = new MemberController();
mc.run();
}
}
private Member[] mArr;
로 Member 배열로 필드를 등록함으로써 Member 객체만 포함될 수 있게했음MemberList members; MemberList restoreList;
MemberList 타입을 참조하는 필드를 등록this.members = new MemberList(); this.restoreList = new MemberList();
MemberList 객체를 생성함으로써 MemberList 클래스를 통해 배열을 관리, 조작할 수 있음 (MemberList 필드, 메서드 사용)