본문 바로가기
개발자 꿈나무의 하루/01_Boot Camp

(네이버클라우드 부트캠프) 17일차 - 실습프로젝트(CRUD구현하기)

by kk_naks 2024. 6. 18.

1. 클래스 분류하기 

- 클래스의 용도에 따라 패키지를 분리한다.
- myapp
  |- util : 범용적으로 사용되는 클래스  
  |- vo : domain, dto라고도 설정하며 사용자 정의 데이터 분류
  |- command : 세부 명령어를 수행하는 클래스로 기능에 따라서 클래스 분류
  |- App.java : main()메서드를 수행하는 클래스

  1.1 util 패키지

- input 메서드와 같은 여러 클래스에서 (범용적으로)사용되는 메서드들을 저장

 

     - Prompt.java 리팩토링

- Object 자료형은 모든 데이터 타입을 받는다.
- input("메인/%s>",menutitle) - > format = 메인/%s>, menutitle = mainMenuse[0] = "회원"
-> System.out.printf(format + " ", args) = System.out.printf("메인/%s>" + " ", "회원"); 
=> "메인/회원> "
package bitcamp.myapp2.util;

import java.util.Scanner;

public class Prompt {
  static Scanner keyboardScanner = new Scanner(System.in);

  public static String input(String format, Object... args) {
    System.out.printf(format + " ", args);
    return keyboardScanner.nextLine();
  }

  public static int inputInt(String format, Object... args) {
    return Integer.parseInt(input(format, args));
  }


  public static void close() {
    keyboardScanner.close();
  }
}

  1.2 vo 패키지 

- User, Project, Board와 같이 데이터 타입으로 사용되는 파일들을 저장
- 파일을 리팩터링 하면 다음과 같이 에러가 발생 -> 접근지정자의 오류 
- 이전에 default 로 설정이 되어 있어, 다른패키지의 파일을 참고 할 수가 없다
- import 문과 public 문 사용

     - User.java 리팩토링

package bitcamp.myapp2.vo;

public class User {
  private String name;
  private String email;
  private String password;
  private String tel;

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public String getEmail() {
    return email;
  }

  public void setEmail(String email) {
    this.email = email;
  }

  public String getPassword() {
    return password;
  }

  public void setPassword(String password) {
    this.password = password;
  }

  public String getTel() {
    return tel;
  }

  public void setTel(String tel) {
    this.tel = tel;
  }
}

 

  1.2 command 패키지 

- 세부 명령을 수행하는 패키지 모음
- 세부 명령 하나당 많은 양의 소스코드가 존재
- 유지관리 편의성을 위해 기능별로 파일을 관리하는 것이 좋다.

 

     - UserCommand.java 리팩토링

package bitcamp.myapp2.command;

import bitcamp.myapp2.util.Prompt;
import bitcamp.myapp2.vo.User;

public class UserCommand {
  private static final int MAX_SIZE = 10;
  private static final User[] users = new User[MAX_SIZE];
  private static int userLength = 0;

  public static void excuteUserCommand(String command) {
    System.out.printf("[%s]\n", command);
    switch (command) {
      case "등록":
        addUser();
        break;
      case "목록":
        listUser();
        break;
      case "조회":
        viewUser();
        break;
      case "변경":
        updateUser();
        break;
      case "삭제":
        deleteUser();
        break;
    }
  }

  private static void addUser() {
    User user = new User();
    user.setName(Prompt.input("이름?"));
    user.setEmail(Prompt.input("이메일?"));
    user.setPassword(Prompt.input("암호?"));
    user.setTel(Prompt.input("연락처?"));
    users[userLength++] = user;
  }

  private static void listUser() {
    System.out.println("번호 이름 이메일");
    for (int i = 0; i < userLength; i++) {
      User user = users[i];
      System.out.printf("%d %s %s\n", i + 1, user.getName(), user.getEmail());
    }
  }

  private static void viewUser() {
    int userNo = Integer.parseInt(Prompt.input("회원번호?"));
    if (userNo < 1 || userNo > userLength) {
      System.out.println("없는 회원입니다.");
      return;
    }
    User user = users[userNo - 1];
    System.out.printf("이름 : %s\n", user.getName());
    System.out.printf("이메일 : %s\n", user.getEmail());
    System.out.printf("연락처 : %s\n", user.getTel());
  }

  private static void updateUser() {
    int userNo = Integer.parseInt(Prompt.input("회원번호?"));
    if (userNo < 1 || userNo > userLength) {
      System.out.println("없는 회원입니다.");
      return;
    }
    User user = users[userNo - 1];
    user.setName(Prompt.input("이름(%s):", user.getName()));
    user.setEmail(Prompt.input("이메일(%s):", user.getEmail()));
    user.setPassword(Prompt.input("비밀번호(%s):", user.getPassword()));
    user.setTel(Prompt.input("연락처(%s):", user.getTel()));
    System.out.println("변경했습니다.");
  }

  private static void deleteUser() {
    int userNo = Integer.parseInt(Prompt.input("회원번호?"));
    if (userNo < 1 || userNo > userLength) {
      System.out.println("없는 회원입니다.");
      return;
    }
    for (int i = userNo; i < userLength; i++) {
      users[i - 1] = users[i];
    }
    userLength--;
    users[userLength] = null;
    System.out.println("삭제했습니다.");
  }
}

 

2. 프로젝트CRUD 만들기

  2.1 Project 데이터타입 정의 및 기본 CRUD 구현하기

- Project의 데이터 타입은 ["프로젝트명", "프로젝트 설명", "시작기간", "종료기간", "팀원"]으로 구성 되어 있다.
- CRUD의 구성은 기존 회원의 구조와 동일 하다.

 

     - Project 구성

package bitcamp.myapp2.vo;

public class Project {
  private String title;
  private String description;
  private String startDate;
  private String endDate;
  private final User[] users = new User[10];
  private int memberSize;

  public String getTitle() {
    return title;
  }

  public void setTitle(String title) {
    this.title = title;
  }

  public String getDescription() {
    return description;
  }

  public void setDescription(String description) {
    this.description = description;
  }

  public String getStartDate() {
    return startDate;
  }

  public void setStartDate(String startDate) {
    this.startDate = startDate;
  }

  public String getEndDate() {
    return endDate;
  }

  public void setEndDate(String endDate) {
    this.endDate = endDate;
  }

  public int getMemberSize() {
    return memberSize;
  }

  public void setMemberSize(int memberSize) {
    this.memberSize = memberSize;
  }

  public User[] getUsers() {
    return users;
  }
}

 

     - Project 구성

package bitcamp.myapp2.command;

public class ProjectCommand {
  static void excuteProjectCommand(String command) {
    System.out.printf("[%s]\n", command);
    switch (command) {
      case "등록":
        addProject();
        break;
      case "목록":
        listProject();
        break;
      case "조회":
        viewProject();
        break;
      case "변경":
        updateProject();
        break;
      case "삭제":
        deleteProject();
        break;
    }
  }

  static void addProject() {
    System.out.println("프로젝트 등록");
  }

  static void listProject() {
    System.out.println("프로젝트 목록");
  }

  static void viewProject() {
    System.out.println("프로젝트 조회");
  }

  static void updateProject() {
    System.out.println("프로젝트 변경");
  }

  static void deleteProject() {
    System.out.println("프로젝트 삭제");
  }
}

 

  2.2 addProject()

     - addProject 구성

- 입력 : 프로젝트명, 프로젝트설명, 시작일, 종료일, 팀원[]
팀원 추가 할때의 로직

while (true){
	1. 유저 번호 받기
    2. if 종결조건 (유저 번호 == 0)
    3. users로 부터 유저 객체 생성
    	- 없으면 null  ->  1.으로 돌아가기
        - 있으면 객체에 대입 -> 4.으로 가기
    4. 새로운 객체가 기존의 팀원인지 확인
    4.1 project의 멤버[]에 접근 및 탐색
    	- 있으면 true -> 1.으로 돌아가기
        - 없으면 false -> 5.으로 가기
   	5. project의 멤버[]에 추가 
}

 

     - addProject

  static void addProject() {
    Project project = new Project();
    project.setTitle(Prompt.input("프로젝트명?"));
    project.setDescription(Prompt.input("프로젝트설명?"));
    project.setStartDate(Prompt.input("시작일?"));
    project.setEndDate(Prompt.input("종료일?"));
    while (true) {
      int userNo = Prompt.inputInt("추가할 팀원 번호?(종료:0)");
      if (userNo == 0) {
        break;
      }
      User user = UserCommand.findByNo(userNo);
      if (user == null) {
        System.out.println("없는 팀원입니다.");
        continue;
      }
      if (project.contain(user)) {
        System.out.printf("'%s'은 현재 팀원입니다.", user.getName());
        continue;
      }
      project.addMember(user);
    }
    projects[ProjectLength++] = project;
  }
  
  //UserCommand.java
  public static User findByNo(userNo){
    if (userNo < 1 || userNo > userLength) {
      return null;
    }
    return users[userNo - 1];
  }
  
  //ProjectCommand.java
  public static boolean contain(User user){
  	for (int i = 0; i < memberLength; i++){
    	User member = users[i]
    	if(user.getName().equals(member.getName()){
        	return true;
		}
   	 }
    return false;
  }

 

  2.3 listProject()

     - listProject 구성

- 번호 프로젝트명 기간 
- getter method()를 사용 하여 가져오기

 

     - listProject

  static void listProject() {
    System.out.println("번호 프로젝트명 기간");
    for (int i = 0; i < projectLength; i++) {
      Project project = projects[i];
      System.out.printf("%d %s %s~%s\n", i + 1, project.getTitle(), project.getStartDate(),
          project.getEndDate());
    }
  }

 

  2.4 viewProject()

     - viewProject 구성

- 번호를 입력 받아 
- 예외인 경우 return으로 메서드 종료
- 해당하는 번호의 project에 접근하여 getter method()로 출력

 

     - viewProject

  static void viewProject() {
    int projectNo = Prompt.inputInt("프로젝트번호?");
    if (projectNo < 1 || projectNo >= projectLength) {
      System.out.println("없는 프로젝트번호 입니다.");
      return;
    }
    Project project = projects[projectNo - 1];
    System.out.printf("프로젝트명: %s\n", project.getTitle());
    System.out.printf("설명: %s\n", project.getDescription());
    System.out.printf("기간: %s ~ %s\n", project.getStartDate(), project.getEndDate());
    System.out.println("팀원");
    for (int i = 0; i < project.getMemberSize(); i++) {
      User user = project.getMember(i);
      System.out.printf("- %s\n", user.getName());
    }
    System.out.println("프로젝트 조회");
  }
  
  //Project.java
  public User getMember(int index){
  	return users[inx];
   }

 

  2.5 updateProject()

     - updateProject 구성

- 프로젝트~기간 수정
- 멤버 삭제
- 멤버 추가 (addMember와 동일)
static void updateProject() {
    int projectNo = Prompt.inputInt("프로젝트번호?");
    if (projectNo < 1 || projectNo >= projectLength) {
      System.out.println("없는 프로젝트번호 입니다.");
      return;
    }
    Project project = projects[projectNo - 1];
    project.setTitle(Prompt.input("프로젝트명(%s)?", project.getTitle()));
    project.setDescription(Prompt.input("설명(%s)?", project.getDescription()));
    project.setStartDate(Prompt.input("시작일(%s)?", project.getStartDate()));
    project.setEndDate(Prompt.input("종료일(%s)?", project.getEndDate()));
    System.out.println("팀원:");
    deleteMembers(project);
    addMembers(project);
  }
  
static void deleteMembers(Project project) {
    for (int i = project.getMemberSize() - 1; i >= 0; i--) {
      User user = project.getMember(i);
      String str = Prompt.input("팀원(%s) 삭제?", user.getName());
      if (str.equalsIgnoreCase("y")) {
        project.deleteMember(i);
        System.out.printf("'%s' 팀원을 삭제합니다.", user.getName());
      } else {
        System.out.printf("'%s' 팀원을 유지합니다.", user.getName());
      }
    }
}

//project.java
  public void deleteMember(int index) {
    for (int i = index + 1; i < memberSize; i++) {
      users[i - 1] = users[i];
    }
    users[--memberSize] = null;
  }

 

  2.6 deleteProject()

  static void deleteProject() {
    int projectNo = Prompt.inputInt("프로젝트번호?");
    if (projectNo < 1 || projectNo >= projectLength) {
      System.out.println("없는 프로젝트번호 입니다.");
      return;
    }
    for (int i = projectNo; i < projectLength; i++) {
      projects[i - 1] = projects[i];
    }
    projects[--projectLength] = null;
  }

 

3. 프로젝트CRUD 

  3.1 projectCommand

package bitcamp.myapp2.command;

import bitcamp.myapp2.util.Prompt;
import bitcamp.myapp2.vo.Project;
import bitcamp.myapp2.vo.User;

public class ProjectCommand {
  private static final int MAX_SIZE = 10;
  private static final Project[] projects = new Project[MAX_SIZE];
  private static int projectLength = 0;


  public static void excuteProjectCommand(String command) {
    System.out.printf("[%s]\n", command);
    switch (command) {
      case "등록":
        addProject();
        break;
      case "목록":
        listProject();
        break;
      case "조회":
        viewProject();
        break;
      case "변경":
        updateProject();
        break;
      case "삭제":
        deleteProject();
        break;
    }
  }

  static void addProject() {
    Project project = new Project();
    project.setTitle(Prompt.input("프로젝트명?"));
    project.setDescription(Prompt.input("설명?"));
    project.setStartDate(Prompt.input("시작일?"));
    project.setEndDate(Prompt.input("종료일?"));
    addMembers(project);
    projects[projectLength++] = project;
  }

  static void listProject() {
    System.out.println("번호 프로젝트명 기간");
    for (int i = 0; i < projectLength; i++) {
      Project project = projects[i];
      System.out.printf("%d %s %s~%s\n", i + 1, project.getTitle(), project.getStartDate(),
          project.getEndDate());
    }
  }

  static void viewProject() {
    int projectNo = Prompt.inputInt("프로젝트번호?");
    if (projectNo < 1 || projectNo >= projectLength) {
      System.out.println("없는 프로젝트번호 입니다.");
      return;
    }
    Project project = projects[projectNo - 1];
    System.out.printf("프로젝트명: %s\n", project.getTitle());
    System.out.printf("설명: %s\n", project.getDescription());
    System.out.printf("기간: %s ~ %s\n", project.getStartDate(), project.getEndDate());
    System.out.println("팀원");
    for (int i = 0; i < project.getMemberSize(); i++) {
      User user = project.getMember(i);
      System.out.printf("- %s\n", user.getName());
    }
    System.out.println("프로젝트 조회");
  }

  static void updateProject() {
    int projectNo = Prompt.inputInt("프로젝트번호?");
    if (projectNo < 1 || projectNo >= projectLength) {
      System.out.println("없는 프로젝트번호 입니다.");
      return;
    }
    Project project = projects[projectNo - 1];
    project.setTitle(Prompt.input("프로젝트명(%s)?", project.getTitle()));
    project.setDescription(Prompt.input("설명(%s)?", project.getDescription()));
    project.setStartDate(Prompt.input("시작일(%s)?", project.getStartDate()));
    project.setEndDate(Prompt.input("종료일(%s)?", project.getEndDate()));
    System.out.println("팀원:");
    deleteMembers(project);
    addMembers(project);
  }

  static void deleteProject() {
    int projectNo = Prompt.inputInt("프로젝트번호?");
    if (projectNo < 1 || projectNo >= projectLength) {
      System.out.println("없는 프로젝트번호 입니다.");
      return;
    }
    for (int i = projectNo; i < projectLength; i++) {
      projects[i - 1] = projects[i];
    }
    projects[--projectLength] = null;
  }

  static void addMembers(Project project) {
    while (true) {
      int userNo = Prompt.inputInt("추가할 팀원 번호?(종료:0)");
      if (userNo == 0) {
        break;
      }
      User user = UserCommand.findByNo(userNo);
      if (user == null) {
        System.out.println("없는 팀원입니다.");
        continue;
      }
      if (project.contain(user)) {
        System.out.printf("'%s'은 현재 팀원입니다.", user.getName());
        continue;
      }
      project.addMember(user);
    }
  }

  static void deleteMembers(Project project) {
    for (int i = project.getMemberSize() - 1; i >= 0; i--) {
      User user = project.getMember(i);
      String str = Prompt.input("팀원(%s) 삭제?", user.getName());
      if (str.equalsIgnoreCase("y")) {
        project.deleteMember(i);
        System.out.printf("'%s' 팀원을 삭제합니다.", user.getName());
      } else {
        System.out.printf("'%s' 팀원을 유지합니다.", user.getName());
      }
    }
  }
}

  3.2 project

package bitcamp.myapp2.vo;

public class Project {
  private final User[] users = new User[10];
  private String title;
  private String description;
  private String startDate;
  private String endDate;
  private int memberSize;

  public String getTitle() {
    return title;
  }

  public void setTitle(String title) {
    this.title = title;
  }

  public String getDescription() {
    return description;
  }

  public void setDescription(String description) {
    this.description = description;
  }

  public String getStartDate() {
    return startDate;
  }

  public void setStartDate(String startDate) {
    this.startDate = startDate;
  }

  public String getEndDate() {
    return endDate;
  }

  public void setEndDate(String endDate) {
    this.endDate = endDate;
  }

  public int getMemberSize() {
    return memberSize;
  }

  public void setMemberSize(int memberSize) {
    this.memberSize = memberSize;
  }

  public User[] getUsers() {
    return users;
  }

  public User getMember(int index) {
    return users[index];
  }

  public boolean contain(User user) {
    for (int i = 0; i < memberSize; i++) {
      User member = users[i];
      if (user.getName().equals(member.getName())) {
        return true;
      }
    }
    return false;
  }

  public void addMember(User user) {
    users[memberSize++] = user;
  }

  public void deleteMember(int index) {
    for (int i = index + 1; i < memberSize; i++) {
      users[i - 1] = users[i];
    }
    users[--memberSize] = null;
  }
}