JAVAIARY

학점 부여 프로그램 본문

review

학점 부여 프로그램

shiherlis 2022. 10. 3. 23:15

전체 소스코드

https://github.com/Javaiary/selfEdu/tree/main/JAVA/codeBox/gradeEvaluation

 

GitHub - Javaiary/selfEdu

Contribute to Javaiary/selfEdu development by creating an account on GitHub.

github.com

1. 문제 정의  
 *  Ezen 이라는 학교가 있다. 
 *  이 학교에는 5명의 학생들이 수업을 듣습니다.
 *  과목은 국어/수학 2개, 각 학생은 두 과목을 모두 수강한다.
 *  전공은 국어교육학/컴퓨터공학 2가지
 *  국어교육학과는 국어가 필수과목이고, 컴퓨터 공학과는 수학이 필수과목이다.
 *  이번 학기에 성적이 아래와 같이 나왔다.
 *  -------------------------------------------------------------------------
 *  이름  학번 전공 필수과목 국어점수 수학점수
 *  스티브잡스      20220915   국어교육학과  국어   95   56
 *  이순신             20220916   컴퓨터공학과  수학   94   98
 *  리누스토발즈  20220917   국어교육학과  국어   100   88
 *  제임스고슬링  20220918   국어교육학과  국어   89   94
 *  이도                20220919   컴퓨터공학과  수학   83   56
 * 
 *  학점을 부여하는 방법은 여러가지가 있습니다. 
 *  1) A~F 부여하는 방법
 *  2) S~F 부여하는 방법 등
 * 
 *  일반 과목이라면 A~F로, 필수과목이라면 S~F로 분류합니다.
 * 
 *  점수에 따른 학점 부여 기준
 *  필수과목학점
 *  S A B C D F
 *  ---------------------------------------------
 *  95~100 90~94 80~89 70~79 60~69 60미만
 * 
 *  일반과목학점
 *  A B C D F
 *  -------------------------------------
 *  90~100 80~89 70~79 55~69 55미만
 * 
 *  학점 결과를 아래와 같이 나올 수 있도록 구현
 * 
 *  국어과목 학점 결과 >>> 
 *  ------------------------------------------------
 *  이름  학번 필수과목 점수 학점
 *  ------------------------------------------------
 *  스티브잡스     20220915     국어 95  S   
 *  이순신            20220916    수학    94  A
 *  리누스토발즈  20220917     국어 100  S  
 *  제임스고슬링  20220918     국어  89  B   
 *  이도                20220919     수학 83  B
 *  ================================================
 * 
 *  수학과목 학점 결과 >>> 
 *  ------------------------------------------------
 *  이름  학번 필수과목 점수 학점
 *  ------------------------------------------------
 *  스티브잡스   20220915     국어 56  D   
 *  이순신           20220916    수학 98  S
 *  리누스토발즈  20220917     국어     88  B  
 *  제임스고슬링  20220918     국어     94  A   
 *  이도               20220919     수학 56  F
 *  ================================================
 *  학점 정책이 추가되는 경우를 고려하여 객체를 설계하고 인터페이스(interface)를 선언하여
 *  각 정책이 해당 인터페이스를 구현하도록 하시오.
 * 
 * 2. UML 클래스 정의, 관계
 * 3. 구현
 * 4. 테스트
 * 5. 업그레이드
 *  - 과목과 학점 정책이 추가
 *  - 골프 과목이 새로 개설되고 이 과목의 평가 정책은 pass/Non-Pass로 정해짐
 *  - 70점 이상인 경우 pass, 미만인 경우 fail
 *  - 전체 5명 학생 중 3명만 수강신청함
 *  - 학점 결과를 다음과 같이 구현하시오.


 *  수학과목 학점 결과 >>> 
 *  ------------------------------------------------
 *  이름  학번 필수과목 점수 학점
 *  ------------------------------------------------
 *  스티브잡스   20220915     국어 95  P   
 *  이순신          20220916    수학 85  P
 *  리누스토발즈  20220917   국어  55  N
 *  ================================================

 


1. 학점부여 인터페이스를 상속받게하여 각각의 학점정책(전공, 비전공,패논패)을 설계한다.

 

public interface GradeEvaluation {
	String getGrade(int score);
}

 학점부여 인터페이스의 추상메서드

 - 해당 인터페이스를 상속받은 학점 정책 클래스에 getGrade()를 오버라이드하여 각각 다른 정책을 이용할 수 있도록 함


2.  학생, 성적, 과목의 정보를 중복되지 않도록 School  인스턴스를 통해서 생성될 수 있도록 함

 -  학생, 성적, 과목의 각 클래스에 필요한 변수를 선언하고, getter, setter를 생성해 줌

Score 클래스
Student 클래스
Subject 클래스

- School 클래스에 싱글톤 패턴 적용

public class School {
	private static School instance = new School();

	private School() {};	
	// 인스턴스가 아닌 기본 생성자를 호출하는 것을 막기 위해 기본생성자를 private선언해줌

	public static School getInstance() {
		if (instance == null) {
			instance = new School();
		}
		return instance;
	}

- 학생,과목 클래스를 has a 관계로 정의하여 School 클래스에서  사용할 수 있도록 하기 위해 멤버 객체 생성

     - 다수의 학생/과목을 입력하기 위해 ArrayList타입 사용

	private ArrayList<Student> students = new ArrayList<>();
	private ArrayList<Subject> subjects = new ArrayList<>();

	public ArrayList<Student> getStudents() {
		return students;
	}

	public ArrayList<Subject> getSubjects() {
		return subjects;
	}

 

- School 클래스에서 호출하여 학생/과목을 추가할 수 있는 메서드 선언

     - set이아닌 ArrayList에 add하는 방식으로 설정

public void addStudent(Student student) {
students.add(student);
}

public void addSubject(Subject subject) {
subjects.add(subject);
}

3. 과목과 학점 정책상수로 지정

public class Constant {
	
	public static final int KOREAN = 1001; 	//국어
	public static final int MATH = 1002;	//수학
	public static final int GOLF = 1003;	//골프
	
	public static final int AB_TYPE = 0;	// 일반과목 학점산출 ABCDF
	public static final int SAB_TYPE = 1;	// 전공과목 학점산출 SABCDF
	public static final int PN_TYPE = 2;	// P/N
}

4. GenerateGradeDisplay 클래스에서 School 인스턴스를 호출해 데이터를 클래스를 불러온 후,

    buffer를 이용해 선택된 학점 정책에 따라 학점을 부여해주고 출력하는 getDisplay() 메서드 선언

  1) School 인스턴스 호출

School school = School.getInstance();

  2) 모든 과목을 불러온 후 , 양식에 맞추어 출력하는 getDisplay() 메서드 선언

	private StringBuffer buffer = new StringBuffer();
	
	public String getDisplay() {
		ArrayList<Subject> subjects = school.getSubjects();
		
		for(Subject subject: subjects) {
			makeHeader(subject);
			makeBody(subject);
			makeFooter(subject);
		}
		
		return buffer.toString();
	}

  - 모든 과목에 똑같이 반복되는 부분은 상수로 선언하여 반복사용 (TITLE, LINE ....)

  - Header 

private void makeHeader(Subject subject) {
	buffer.append("\t" + subject.getSubjectName());
	buffer.append(GenerateGradeDisplay.TITLE);
	buffer.append(GenerateGradeDisplay.LINE1);
	buffer.append(HEADER);
	buffer.append(GenerateGradeDisplay.LINE1);
}

- Body

private void makeBody(Subject subject) {
	ArrayList<Student> students = subject.getStudents();
	for(int i = 0; i <students.size();i++) {
		Student student = students.get(i);
		buffer.append(student.getStudentName());
		
		if (student.getStudentName().length() >= 6) {
			buffer.append("\t");
		}
		else buffer.append("\t\t");
		buffer.append(student.getStudentId());
		buffer.append("  ");
		buffer.append(student.getMajorSubject().getSubjectName());
		buffer.append("\t");
		GetScoreGrade(student, subject);	//학생별 해당과목 학점계산
		buffer.append("\n");
	}
		buffer.append(LINE2);
}

  - GetScoreGrade() : 선택된 학점 정책에 따라 학점을 부여해주는 메서드

private void GetScoreGrade(Student student, Subject subject) {
	ArrayList<Score> scoreList = student.getScores();
	int majorId = student.getMajorSubject().getSubjectId();
	
	//학점 평가 클래스
	GradeEvaluation[] gradeEvaluation = 
    	{ new BasicEvaluation(), new MajorEvaluation(), new PNPEvlaluation()};
	
	for(int i = 0; i < scoreList.size(); i++) {			//학생이 가진 점수들
		Score score = scoreList.get(i);
        //현재 학점을 산출한 과목 비교
		if (score.getSubject().getSubjectId() == subject.getSubjectId()) {	
			String grade;
            //필수과목학점
			if(score.getSubject().getSubjectId() == majorId) {	
				grade = gradeEvaluation[Constant.SAB_TYPE].getGrade(score.getScore());
			}
            //패논패과목학점
			else if (score.getSubject().getSubjectId() == 1003) {
				grade = gradeEvaluation[Constant.PN_TYPE].getGrade(score.getScore());
			}
            //일반과목학점
			else
				grade= gradeEvaluation[Constant.AB_TYPE].getGrade(score.getScore());
			buffer.append(score.getScore());
			buffer.append("\t");
			buffer.append(grade);
		}	
	}
}

 -  Footer

private void makeFooter(Subject subject) {
		buffer.append("\n");
		
	}

5. UiMain 클래스에서 School 인스턴스를 통해 학생 등록, 과목 수강, 성적입력을 한 후  

GenerateGradeDisplay 멤버변수로 학점산출프로그램을 불러와 실행

1) UiMain 클래스내부에 학생 추가, 과목별 성적입력, 과목 추가 메서드 선언

// [1] 학생 추가 메서드
public void createStudent() {
    //학생 정보 입력(이름, 학번, 필수과목)
	Student student1 = new Student("스티브잡스", 20220915, korean);  
		
    //학생 등록(추가)
    eSchool.addStudent(student1);
        
    // 과목 수강 등록
	korean.register(student1);

	//과목별 성적 입력
	addScoreForStudent(student1, korean, 95);
}
	
// [2] 학생의 과목별 성적입력 메서드   
private void addScoreForStudent(Student student, Subject subject, int score) {
		Score score1 = new Score(student.getStudentId(), subject, score);
		student.addSubjectScore(score1);
}

// [3] 과목 신설 메서드
public void createSubject() {
	//korean 과목 신설 (과목번호, 과목이름)
	korean = new Subject(Constant.KOREAN, "국어");
    
    //학교에 korean과목 추가
	eSchool.addSubject(korean);
		
	//else if를 추가하지 않고 직접 학점부여방식을 지정해주는 방법
	//golf.setGradeType(Constant.PN_TYPE);
    
}

2) 클래스 내부에 School 인스턴스 생성, Subject 타입 과목 선언.

    getDisplay 메서드 호출을 위한 GenerateGradeDisplay 멤버변수 생성

	School eSchool = School.getInstance();
	Subject korean;

	GenerateGradeDisplay gradeDisplay = new GenerateGradeDisplay();

3) 실행

public static void main(String[] args) {

	UiMain uiMain = new UiMain();
		
	uiMain.createSubject();				//시험과목 생성
	uiMain.createStudent();				//시험 응시 학생 생성
			
	String display = uiMain.gradeDisplay.getDisplay();
	System.out.println(display);
}

이해가 안 될 땐 ctrl+클릭/ f3 버튼을 통해 타고 타고 올라가면서 확인하는 게 도움이 많이 됐다 ㅠ

'review' 카테고리의 다른 글

linkedList 노드의 추가와 삭제  (0) 2022.09.09
Singleton pattern II  (0) 2022.09.07
Singleton Pattern I  (0) 2022.09.05
ArrayList 출력 방법  (0) 2022.09.04