본문 바로가기
  • 코딩, 허쌤이 떠먹여 줄게
BackEnd/Java

15장. 미니 프로젝트 & 실습

by 허쌤 2026. 1. 4.

15장. 미니 프로젝트 & 실습

프로젝트 개요

이 장에서는 지금까지 배운 Java 지식을 종합하여 학생 관리 시스템을 만들어봅니다.

프로젝트 목표

  1. 콘솔 기반 애플리케이션 개발
  2. 객체지향 프로그래밍 원칙 적용
  3. 코드 리팩토링을 통한 개선
  4. 프로젝트 구조 설계 이해

프로젝트 기능

  • 학생 정보 등록 (이름, 학번, 나이, 전공)
  • 학생 정보 조회 (전체 조회, 학번으로 조회)
  • 학생 정보 수정
  • 학생 정보 삭제
  • 학생 정보 파일 저장/불러오기

객체지향 구조 설계

클래스 설계

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. 가독성 향상: 코드를 읽기 쉽게 만들기
  2. 유지보수성 향상: 수정하기 쉽게 만들기
  3. 재사용성 향상: 코드를 재사용하기 쉽게 만들기
  4. 성능 개선: 불필요한 코드 제거

리팩토링 기법

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단계: 기본 구조 만들기

  1. Student 클래스 생성
  2. StudentService 클래스 생성
  3. 간단한 메뉴 출력

2단계: CRUD 기능 구현

  1. 학생 등록 기능
  2. 학생 조회 기능
  3. 학생 수정 기능
  4. 학생 삭제 기능

3단계: 파일 저장/불러오기

  1. StudentRepository 클래스 생성
  2. 파일 저장 기능
  3. 파일 불러오기 기능

4단계: 리팩토링

  1. 코드 중복 제거
  2. 메서드 분리
  3. 예외 처리 개선
  4. 입력 검증 추가

5단계: 테스트 및 개선

  1. 각 기능 테스트
  2. 예외 상황 테스트
  3. 코드 리뷰
  4. 개선 사항 적용

프로젝트 확장 아이디어

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. 기능 추가

  • 성적 관리
  • 출석 관리
  • 통계 기능
  • 검색 기능

연습 문제

  1. 기본 구조 만들기

    • Student 클래스와 StudentService 클래스를 만드세요.
  2. CRUD 구현

    • 학생 등록, 조회, 수정, 삭제 기능을 구현하세요.
  3. 파일 저장

    • 학생 정보를 파일에 저장하고 불러오는 기능을 구현하세요.
  4. 리팩토링

    • 코드를 리팩토링하여 가독성과 유지보수성을 개선하세요.
  5. 예외 처리

    • 적절한 예외 처리를 추가하세요.
  6. 입력 검증

    • 사용자 입력을 검증하는 기능을 추가하세요.

프로젝트 완성 체크리스트

  • Student 클래스 구현
  • StudentService 클래스 구현
  • StudentRepository 클래스 구현
  • StudentController 클래스 구현
  • CRUD 기능 모두 구현
  • 파일 저장/불러오기 기능 구현
  • 예외 처리 구현
  • 입력 검증 구현
  • 코드 리팩토링 완료
  • 주석 작성 완료
  • README 작성 완료

다음 단계

이 프로젝트를 완성한 후에는:

  1. 고급 기능 추가: 정렬, 검색, 통계 등
  2. 다른 프로젝트 시도: 도서 관리, 주소록 등
  3. 프레임워크 학습: Spring, Hibernate 등
  4. 테스트 작성: JUnit을 사용한 단위 테스트
  5. 버전 관리: Git을 사용한 프로젝트 관리

마무리

이 장에서는 지금까지 배운 Java 지식을 종합하여 실제 프로젝트를 만들어봤습니다.

프로젝트를 만들면서:

  • 객체지향 프로그래밍 원칙을 적용했습니다
  • 코드를 리팩토링하여 개선했습니다
  • 프로젝트 구조를 설계했습니다

이 경험을 바탕으로 더 큰 프로젝트에 도전해보세요!