NBC Management - 2

이재현·2024년 8월 8일

Project

목록 보기
4/5

🩵 프로젝트 설명

이전에 시작한 내일 배움 캠프 수강생들에 대한 정보를 관리하는 프로그램이다.

일반적으로는 수강생들의 정보와 점수 정보를 관리하는 프로그램으로, 자바의 기초를 다시 한번 복습한다는 느낌으로 진행할 예정이다.

이번에는 이전에 작성한 NBC Management Program에서 추가된 내용을 작성해 보려 한다.




🩵 기능 설명

기능 설명은 지난번에 진행했으므로 이번에는 요구사항 부분만 간단히 적어두고 넘어가겠다.

⭐ 필수 요구사항

  1. 수강생 관리
    수강생 정보 등록 (수강생의 고유 번호는 중복 불가)
    수강생 목록 조회 (형식은 자유)

  2. 점수 관리
    수강생의 과목별 시험 회차 및 점수 등록
    수강생의 과목별 회차 점수 수정
    수강생의 특정 과목 회차별 등급을 조회

⭐ 추가 요구사항

  1. 수강생 관리
    수강생 정보 수정
    상태별 수강생 목록 조회
    수강생 기록 삭제 (점수 기록까지 전)

  2. 점수 관리
    수강생의 과목별 평균 등급 조회
    특정 상태 수강생들의 필수 과목 평균 등급 조회




🩵 기능 구현

1. 메뉴 작성

메뉴는 출력 부분, displayMenu_Main , displayMenu_StudentInfo , displayMenu_ScoreInfo 부분은 지난번과 동일하다.

변경사항은 이 함수들을 호출하는 부분에서 생겼는데, do-while 문 안쪽에 입력값을 받는 부분에 있어서 예외처리를 진행했다.

	// 메뉴에서 선택지를 입력받는 부분이다.
		do {

            // 메인 메뉴 제공 및 선택값 받기
            displayMenu_Main();
            try {
                choice = scanner.nextInt();
                scanner.nextLine();

                // 선택값에 대한 함수 실행 / 1. 학생 관리 / 2. 점수 관리 / 3. 종료 /
                switch(choice) {
                    case 1:
                        managementStudentInfo();
                        break;
                    case 2:
                        managementScoreInfo();
                        break;
                    case 3:
                        System.out.println("Terminate Management Program.");
                        stop_keyword = "exit";
                        break;
                    default:
                        System.out.println("Is not a valid choice.\nInput right choice again.\n");
                }
            } catch(InputMismatchException e) {
                System.out.println("Invalid input. Please enter a valid integer choice.");
                scanner.nextLine(); // 잘못된 입력을 소비하여 무한 루프 방지
            }

        } while(!stop_keyword.equals("exit"));

이 부분을 try-catch 문으로 감싸는 형태로 작성하고, catch에는 InputMismatchException 을 넣어주었다.

지난번까지는 사실 '예외처리가 필요한가? switch로 걸러질텐데.' 라는 생각을 했었다.

하지만 입력값을 int 형 값으로 받기로 한 이상, 그 이외의 데이터 타입이 입력되면 작동하지 않고 에러가 발생한다는 것을 알았다.

그렇기 때문에 그에 대한 예외처리를 진행한 것이다.


2. Manager Class

선택지에 따른 기능을 수행하기 위한 메서드들을 모아놓기 위해서 별도로 Manager Class 를 작성했으며, 이를 상속받아 자식 클래스를 만들어 두었었다.

만들어져 있긴 하지만, 메인과의 연결만 되어 있을 뿐 사실상 기능 구현들이 안되어 있어서 거의 비어있는 상태였다.

하지만, 이번에 팀원들의 기능 구현이 끝나면서 StudentManagerScoreManager 부분이 새롭게 작성되었다.

아래는 지난번에 작성했던 Manager Class 코드이다.


// 지난번에 작성한 부모클래스 Manager, 자식클래스도 사실 별반 차이는 없다.
public abstract class Manager {

    protected List<String[]> dataList;

    abstract void addData();

    abstract void inquiryData();

    abstract void modifyData();

}

3. StudentData & SubjectData & ScoreData

다른 것들을 설명하기에 앞서 우리의 학생정보와 과목정보, 그리고 점수정보는 어떻게 되어있나를 설명해보려 한다.

  • 학생 정보: 학생 고유번호 , 이름 , 상태 , 수강중인 과목들
  • 과목 정보: 과목 고유번호 , 과목명 , 필수 or 선택
  • 점수 정보: 학생 고유번호 , 과목 고유번호 , 회차 , 점수 , 등급

우리가 사용할 정보들은 위와 같은 형태로 작성을 해야한다.

하지만 우리는 이를 변형해서 점수 정보를 학생 정보에 모두 담아버렸다.

public class StudentData {

    //객체생성 각각 ScoreData
    private int studentId;
    private String studentName;
    int studentState; // 1=Green, 2=Yellow, 3=Red

    public StudentData(int studentId, String name, int state) {
        this.studentId = studentId;
        this.studentName = name;
        this.studentState = state;
    }
	
    // 과목이 필수인지 아닌지, 등급은 어떻게 할 것인지 저장하는 리스트
    // subjectType : 0 = 필수, 1 = 선택
    // 등급 : A = 1, B = 2, C = 3, D = 4, F = 5, N = 6
    ArrayList<Integer> requireAndChoice=new ArrayList<>();
   
    // 과목 리스트와 그 하위인 해당학생의 과목 점수 리스트
    ArrayList<int[]> subjectList = new ArrayList<>();
    int[] subjectDetails = new int[5];

    public void subjectDetailsInput(int subjectId,int subjectType, int score,int round){
    
        subjectDetails = new int[5];

        this.subjectDetails[0] = subjectId;
        this.subjectDetails[1] = subjectType;
        this.subjectDetails[2] = score; //점수 범위0~100
        this.subjectDetails[3] = round; //회차 범위 1~10
        subjectList.add(subjectDetails); 
    }

이렇게 작성하게 되면 좋은 것은 아무래도 점수 정보는 학생의 고유번호와 과목의 고유번호를 가지고 있기 때문에 조회하기 복잡한 경향이 있었는데, 하나로 합치며 학생을 조회하면 그와 연관된 점수 정보 역시 조회할 수 있기 때문에 조회하는 측면에서는 좋다고 볼 수 있다.

다만 단점은 정보의 형태가 너무 복잡하다는 점이 있다.
또한, 객체 내부 필드에 이중배열로 이를 만들어두다 보니 객체를 불러오지 않으면 이 점수정보에 별로도 접근할 수 없다.


3. StudentManager Class

StudentManager Class 에는 부모클래스에서 오버라이딩한 addData() , inquiryData() , modifyData() 와 별도로 작성한 removeData() 가 들어있다.

각각의 메서드에는 팀원들이 작성한 기능들을 호출하는 코드를 작성했다.

public class StudentManager extends Manager {
	...
    public List<StudentData> studentDataList;  // 학생 정보 리스트

    Add studentAdd = new StudentAdd(); // Add 클래스 생성
    Inquiry studentInquiry = new Inquiry(); // Inquiry 클래스 생성
    Modify studentModify = new Modify(); // Modify 클래스 생성
    
    ...
    
    @Override
    public void addData() {
        StudentData studentData = studentAdd.addStudent(); // studentData라는 값을 리턴
        studentDataList.add(studentData);
    }
    
    ...
    @Override
    public void inquiryData() { ... }
    
    @Override
    public void modifyData() { ... ]
    
    public void removeData() { ... }

생성자를 통해 각각에 해당하는 기능들을 새로 생성하고, 각 addData , inquiryData , modifyData 에서 메서드를 호출해서 사용한다.

그에 대한 결과값들은 모두 위에서 생성한 studentDataList 에 저장된다.

또한, 값을 요구하는 메서드들도 있기때문에, 이 studentDataList 에 저장된 데이터를 불러와서 해당하는 값을 찾아서 매개변수로 넣어준다.

public void removeData() {
		// ID조회를 위해 약식으로 수강생 목록 출력
        studentInquiry.inquiryStudentsListShort(studentDataList);
        
        // 수강생 ID 값 입력받기
        int student_ID = -1;
        boolean validInput = false;

        while (!validInput) {
            try {
                System.out.print("Enter Student ID: ");
                student_ID = scanner.nextInt();
                validInput = true; // 올바른 입력을 받았으므로 루프 종료
            } catch (InputMismatchException e) {
                System.out.println("Invalid input. Please enter a valid integer for the Student ID.");
                System.out.println("If you want to continue, input anything.");
                scanner.next(); // 잘못된 입력을 소비하여 무한 루프 방지
            }
        }

        int flag_ID = 0;

        // 입력받은 ID값에 해당하는 StudentData를 리스트에서 찾기
        for(int i = 0; i < studentDataList.size(); i++) {
            StudentData studentData = studentDataList.get(i);
            if(studentData.getStudentId() == student_ID) {
                studentDataList.remove(i);
                flag_ID = 1;
                break;
            }

        }
        if(flag_ID == 0) {
            System.out.println("Their is not exist the ID in Students!");
        }
}

아까 Main 과 마찬가지로 입력값에 대한 try-catch 문을 통해서 예외처리를 해주고 for문을 사용하여 리스트에서 입력받은 값과 일치하는 학생 고유번호를 찾는 방법이다.

flag_ID 를 생성해 기본값을 0으로 두고 찾은 경우 1로 바꾸도록 해놨는데, 이는 반복문이 끝나고 해당하는 값을 찾았는지 판단하기 위해서이다.

값을 찾지 못하였다면 flag_ID 의 값은 여전히 0이기에 if 문이 실행되며 시스템 문장이 출력된다.




🩵 회고

전체적으로 프로그램은 완성이 되었다. 완성된 코드에 대한 링크는 아래에 달아두겠다.

일단 내가 맡은 Main , Manager 부분도 잘 작동하는 지 테스트를 진행했으며, 예외처리도 잘 해두었다고 생각한다.

이번에 처음으로 진행한 팀 프로젝트인 만큼 다른 사람과의 협동에 다소 어려움이 있었다. 예를 들면 Git & Github 에서 공동작업을 진행하면서 흔히 생기는 merge 문제라던지..

아니면 내가 생각한 형태의 코드가 아니라던지.. 다양한 부분들에 있어서 서로 다른 생각을 가진 사람들의 의견과 코드들을 볼 수 있었다.

하지만 결코 나쁘지 않았으며, 내가 가진 코딩에 대한 지식과 활용법이 넓어지는 기회가 될 수 있었다고 생각한다.

❤️ Github 완성된 NBC Management Program

0개의 댓글