15장. 미니 프로젝트 & 실습
프로젝트 개요
이 장에서는 지금까지 배운 Java 지식을 종합하여 학생 관리 시스템을 만들어봅니다.
프로젝트 목표
- 콘솔 기반 애플리케이션 개발
- 객체지향 프로그래밍 원칙 적용
- 코드 리팩토링을 통한 개선
- 프로젝트 구조 설계 이해
프로젝트 기능
- 학생 정보 등록 (이름, 학번, 나이, 전공)
- 학생 정보 조회 (전체 조회, 학번으로 조회)
- 학생 정보 수정
- 학생 정보 삭제
- 학생 정보 파일 저장/불러오기
객체지향 구조 설계
클래스 설계
1. Student 클래스 (도메인 모델)
학생 정보를 담는 엔티티 클래스입니다.
public class Student {
private String studentId;
private String name;
private int age;
private String major;
// 생성자, getter, setter
}
2. StudentService 클래스 (비즈니스 로직)
학생 관리 비즈니스 로직을 처리하는 서비스 클래스입니다.
public class StudentService {
private List<Student> students;
public void addStudent(Student student) { }
public Student findStudent(String studentId) { }
public void updateStudent(Student student) { }
public void deleteStudent(String studentId) { }
public List<Student> getAllStudents() { }
}
3. StudentRepository 클래스 (데이터 접근)
학생 데이터를 저장하고 불러오는 저장소 클래스입니다.
public class StudentRepository {
public void saveToFile(List<Student> students) { }
public List<Student> loadFromFile() { }
}
4. StudentController 클래스 (컨트롤러)
사용자 입력을 받아 서비스를 호출하는 컨트롤러 클래스입니다.
public class StudentController {
private StudentService studentService;
public void run() {
// 메뉴 표시 및 사용자 입력 처리
}
}
설계 원칙 적용
1. 단일 책임 원칙 (SRP)
각 클래스는 하나의 책임만 가집니다.
Student: 학생 데이터 표현StudentService: 비즈니스 로직 처리StudentRepository: 데이터 저장/불러오기StudentController: 사용자 인터페이스 처리
2. 캡슐화
데이터와 메서드를 하나의 클래스로 묶고, 접근 제어자를 사용합니다.
public class Student {
private String studentId; // private으로 캡슐화
public String getStudentId() { // getter로 접근
return studentId;
}
}
3. 의존성 주입
컨트롤러가 서비스를 사용하도록 의존성을 주입합니다.
public class StudentController {
private StudentService studentService;
public StudentController(StudentService studentService) {
this.studentService = studentService;
}
}
콘솔 기반 미니 프로젝트
메뉴 구조
=== 학생 관리 시스템 ===
1. 학생 등록
2. 학생 조회 (전체)
3. 학생 조회 (학번)
4. 학생 수정
5. 학생 삭제
6. 파일 저장
7. 파일 불러오기
0. 종료사용자 입력 처리
Scanner를 사용하여 사용자 입력을 받습니다.
Scanner scanner = new Scanner(System.in);
int choice = scanner.nextInt();
scanner.nextLine(); // 버퍼 비우기
예외 처리
사용자 입력 오류와 파일 처리 오류를 처리합니다.
try {
// 코드
} catch (NumberFormatException e) {
System.out.println("숫자를 입력해주세요.");
} catch (IOException e) {
System.out.println("파일 처리 오류: " + e.getMessage());
}
코드 리팩토링
리팩토링이란?
리팩토링은 코드의 기능은 유지하면서 구조를 개선하는 것입니다.
리팩토링 목표
- 가독성 향상: 코드를 읽기 쉽게 만들기
- 유지보수성 향상: 수정하기 쉽게 만들기
- 재사용성 향상: 코드를 재사용하기 쉽게 만들기
- 성능 개선: 불필요한 코드 제거
리팩토링 기법
1. 메서드 추출 (Extract Method)
긴 메서드를 작은 메서드로 분리합니다.
// 리팩토링 전
public void processStudent() {
System.out.println("학생 정보를 입력하세요.");
String name = scanner.nextLine();
int age = Integer.parseInt(scanner.nextLine());
// ... 많은 코드
}
// 리팩토링 후
public void processStudent() {
Student student = inputStudentInfo();
studentService.addStudent(student);
}
private Student inputStudentInfo() {
System.out.println("학생 정보를 입력하세요.");
String name = scanner.nextLine();
int age = Integer.parseInt(scanner.nextLine());
return new Student(name, age);
}
2. 클래스 분리 (Extract Class)
큰 클래스를 작은 클래스로 분리합니다.
// 리팩토링 전: 모든 기능이 하나의 클래스에
public class StudentManager {
// 학생 관리
// 파일 처리
// 사용자 입력
}
// 리팩토링 후: 책임별로 분리
public class StudentService { }
public class StudentRepository { }
public class StudentController { }
3. 상수 추출 (Extract Constant)
매직 넘버나 문자열을 상수로 추출합니다.
// 리팩토링 전
if (age < 18) { }
// 리팩토링 후
private static final int MIN_AGE = 18;
if (age < MIN_AGE) { }
4. 변수명 개선 (Rename Variable)
의미 있는 변수명을 사용합니다.
// 리팩토링 전
String s = "홍길동";
// 리팩토링 후
String studentName = "홍길동";
프로젝트 리뷰
코드 리뷰 체크리스트
1. 코드 품질
- 변수명이 의미 있게 지어졌는가?
- 메서드가 하나의 책임만 수행하는가?
- 중복 코드가 없는가?
- 주석이 적절히 작성되었는가?
2. 객체지향 원칙
- 단일 책임 원칙을 지켰는가?
- 캡슐화가 잘 되어 있는가?
- 상속이 적절히 사용되었는가?
- 다형성이 활용되었는가?
3. 예외 처리
- 예외 처리가 적절한가?
- 사용자에게 친절한 오류 메시지를 제공하는가?
- 리소스가 제대로 해제되는가?
4. 성능
- 불필요한 객체 생성이 없는가?
- 효율적인 알고리즘을 사용하는가?
- 메모리 누수가 없는가?
개선 사항
1. 입력 검증 추가
public boolean isValidAge(int age) {
return age > 0 && age < 150;
}
public boolean isValidStudentId(String studentId) {
return studentId != null && !studentId.trim().isEmpty();
}
2. 에러 메시지 개선
// 나쁜 예
System.out.println("오류");
// 좋은 예
System.out.println("오류: 학생을 찾을 수 없습니다. (학번: " + studentId + ")");
3. 로깅 추가
import java.util.logging.Logger;
private static final Logger logger = Logger.getLogger(StudentService.class.getName());
public void addStudent(Student student) {
logger.info("학생 추가: " + student.getStudentId());
students.add(student);
}
프로젝트 구조
디렉토리 구조
project/
├── src/
│ ├── model/
│ │ └── Student.java
│ ├── service/
│ │ └── StudentService.java
│ ├── repository/
│ │ └── StudentRepository.java
│ ├── controller/
│ │ └── StudentController.java
│ └── Main.java
├── data/
│ └── students.txt
└── README.md패키지 구조
package com.studentmanagement.model;
package com.studentmanagement.service;
package com.studentmanagement.repository;
package com.studentmanagement.controller;
실습 단계
1단계: 기본 구조 만들기
- Student 클래스 생성
- StudentService 클래스 생성
- 간단한 메뉴 출력
2단계: CRUD 기능 구현
- 학생 등록 기능
- 학생 조회 기능
- 학생 수정 기능
- 학생 삭제 기능
3단계: 파일 저장/불러오기
- StudentRepository 클래스 생성
- 파일 저장 기능
- 파일 불러오기 기능
4단계: 리팩토링
- 코드 중복 제거
- 메서드 분리
- 예외 처리 개선
- 입력 검증 추가
5단계: 테스트 및 개선
- 각 기능 테스트
- 예외 상황 테스트
- 코드 리뷰
- 개선 사항 적용
프로젝트 확장 아이디어
1. 데이터베이스 연동
파일 저장 대신 데이터베이스를 사용합니다.
public class StudentRepository {
public void saveToDatabase(Student student) {
// JDBC를 사용하여 DB에 저장
}
}
2. GUI 추가
콘솔 대신 GUI를 사용합니다.
// Java Swing 또는 JavaFX 사용
public class StudentGUI extends JFrame {
// GUI 컴포넌트
}
3. 웹 애플리케이션
웹 애플리케이션으로 확장합니다.
// Spring Boot 등을 사용
@RestController
public class StudentController {
@GetMapping("/students")
public List<Student> getAllStudents() { }
}
4. 기능 추가
- 성적 관리
- 출석 관리
- 통계 기능
- 검색 기능
연습 문제
기본 구조 만들기
- Student 클래스와 StudentService 클래스를 만드세요.
CRUD 구현
- 학생 등록, 조회, 수정, 삭제 기능을 구현하세요.
파일 저장
- 학생 정보를 파일에 저장하고 불러오는 기능을 구현하세요.
리팩토링
- 코드를 리팩토링하여 가독성과 유지보수성을 개선하세요.
예외 처리
- 적절한 예외 처리를 추가하세요.
입력 검증
- 사용자 입력을 검증하는 기능을 추가하세요.
프로젝트 완성 체크리스트
- Student 클래스 구현
- StudentService 클래스 구현
- StudentRepository 클래스 구현
- StudentController 클래스 구현
- CRUD 기능 모두 구현
- 파일 저장/불러오기 기능 구현
- 예외 처리 구현
- 입력 검증 구현
- 코드 리팩토링 완료
- 주석 작성 완료
- README 작성 완료
다음 단계
이 프로젝트를 완성한 후에는:
- 고급 기능 추가: 정렬, 검색, 통계 등
- 다른 프로젝트 시도: 도서 관리, 주소록 등
- 프레임워크 학습: Spring, Hibernate 등
- 테스트 작성: JUnit을 사용한 단위 테스트
- 버전 관리: Git을 사용한 프로젝트 관리
마무리
이 장에서는 지금까지 배운 Java 지식을 종합하여 실제 프로젝트를 만들어봤습니다.
프로젝트를 만들면서:
- 객체지향 프로그래밍 원칙을 적용했습니다
- 코드를 리팩토링하여 개선했습니다
- 프로젝트 구조를 설계했습니다
이 경험을 바탕으로 더 큰 프로젝트에 도전해보세요!
'BackEnd > Java' 카테고리의 다른 글
| 8_1. 회차 은행 어플리케이션 프로그램 (0) | 2026.01.14 |
|---|---|
| 5_1 . 이차원 배열 연습문제 (0) | 2026.01.06 |
| Java와 데이터베이스 연동 (0) | 2026.01.04 |
| 13장. 스레드 & 네트워크(기초) (0) | 2026.01.03 |
| 12장. 메모리 구조 & JVM 이해 (0) | 2026.01.03 |