학생이 제출한 답안을 채점하는 기존 방식의 문제점
// 학생 시험 채점
@Transactional
public void markStudentTest(Long id, StudentTestMarkRequest request) {
StudentTest studentTest = getStudentTestById(id);
ProblemSet problemSet = studentTest.getProblemSet();
int score = 0;
List<String> answerSet = new ArrayList<>(); // 해답
problemSet.getProblems().forEach(problem -> answerSet.add(problem.getAnswer()));
List<String> studentAnswerSet = request.getStudentAnswers();
for (int i = 0; i < studentAnswerSet.size(); i++) {
if (studentAnswerSet.get(i).equals(answerSet.get(i))) {
score++;
}
}
studentTest.setScore(score);
studentTest.setCompleted(Completed.Y);
studentTestRepository.save(studentTest);
}
StudentTestService의 학생시험 채점 method이다.
학생이 시험을 보았을 때, 정답을 적은 request를 StudentTestMarkRequest로 만들어 파라미터로 넘겼다.
@Getter
public class StudentTestMarkRequest {
private Long studentId;
private Long StudentTestId;
private List<String> studentAnswers;
}
기존 채점 방식은 학생이 제출한 정답을 단순 문자열 리스트(List<String> studentAnswers)로 받아, 문제별 정답과 순서대로 비교하는 구조였다. 기본적인 비교에는 문제가 없지만, 다음과 같은 한계점이 존재했다.
- 문제 ID와 유형(type) 정보 부족
- List<String>으로만 처리했을 때, 어떤 문제가 어떤 유형인지 정답은 어떤 형태인지 알기 힘들다.
- 객관식, 주관식, 서술형 문제를 채점할 때, 같은 방식으로 해야한다.
- 정렬 방식의 의존성
- 만약 문제가 무작위로 출제되거나, 문제의 순서가 바뀌는 경우, 채점이 올바르게 이루어지지 않을 위험이 있다.
- 문제별 고유 식별자인 problemId가 없기 때문에, 같은 문제가 두 번 출제될 경우에도 구분이 어렵다.
- 객체 지향적 설계 부족으로 확장성 저하
- 단순한 List<String> 방식은 추가 기능(예: 서술형 문제 자동 채점, 부분 점수 부여 등)을 도입할 때, 기존 로직을 대폭 수정해야 하는 문제가 발생한다.
- 새로운 채점 방식이 추가될 때마다 기존 로직을 변경해야 하므로 유지보수가 어렵다.
DTO를 활용하여 개선
위의 문제점을 해결하기 위해, 학생이 제출한 답안을 단순 List<String>이 아닌 StudentTestAnswerDTO 객체로 관리하는 방식으로 변경한다.
@Getter
public class StudentTestMarkRequest {
private Long studentId;
private Long StudentTestId;
private List<StudentTestAnswerDTO> studentAnswers;
}
@Getter
@Setter
@NoArgsConstructor
public class StudentTestAnswerDTO {
private Long problemId;
private String answer;
private ProblemType problemType;
}
이와 같이 문제 ID, 유형, 답안을 포함하는 객체(StudentTestAnswerDto)를 도입하면 다음과 같은 이점이 있다.
- 문제가 랜덤으로 섞이더라도 문제별 고유 ID(problemId)를 기반으로 정확한 정답 매칭 가능
- 문제 유형(객관식, 주관식, 서술형)에 따라 다른 채점 방식을 적용 가능
'EduClass Project' 카테고리의 다른 글
[Project] 복합 키 적용 전후, MySQL 성능 차이 실험 - MySQLWorkBench (0) | 2025.03.25 |
---|---|
[Project] N:M 매핑에서 복합 키(Composite Key)를 사용할 때 주의할 점 (0) | 2025.03.05 |
[Project] 불필요한 Entity 제거를 통한 데이터베이스 설계 최적화 – Test Entity를 없앤 이유 (0) | 2025.03.05 |
[Project] (4) API 구현(@RequestParam vs @PathVariable) (0) | 2025.02.07 |
[Project] (3) 프로젝트 시작(MVC 패턴, 디렉토리 구조) (1) | 2025.02.05 |