Java 기본편에서 배운 개념을 이용해 작은 콘솔 프로그램을 직접 설계하고 구현합니다.
이 과제는 정답 구조를 맞히는 시험이 아닙니다. 요구사항을 객체로 어떻게 표현하고, 상태와 행동을 어디에 둘지 고민하며, 선택한 이유를 설명하는 것이 목적입니다.
작성할 프로그램은 실제 소스 코드를 자동으로 분석하는 도구가 아닙니다.
프로그램 안에서 다음 정보를 직접 생성합니다.
- 가상의 프로젝트
- 프로젝트에 포함된 모듈
- 각 모듈이 담당하는 계층
- 모듈 사이의 의존 관계
- 적용할 검사 규칙
프로그램은 이 객체들을 검사하고 결과를 콘솔에 출력합니다.
가상 프로젝트 생성
→ 모듈 등록
→ 의존 관계 등록
→ 여러 규칙 실행
→ 성공·실패 결과 출력
다음 내용을 사용해 과제를 완성합니다.
- 클래스, 객체, 인스턴스
- 기본형과 참조형
- 객체 배열
- 객체지향 프로그래밍
- 생성자
- 패키지
- 접근 제어와 캡슐화
- Java 메모리 구조
- static과 final
- 상속과 메서드 오버라이딩
- 추상 클래스와 인터페이스
- 다형적 참조
- 역할과 구현의 분리
다음 기능은 사용하지 않습니다.
- Spring 및 기타 프레임워크
- 데이터베이스
- 파일 입출력과 네트워크
- 컬렉션 프레임워크와 제네릭
- 람다와 Stream
- enum과 record
- 리플렉션과 애노테이션
- 외부 라이브러리
- 실제 Java 또는 Gradle 프로젝트 분석
여러 값을 저장해야 할 때는 배열을 사용합니다. 입력 데이터는 코드에서 직접 생성합니다.
프로그램은 검사 대상 프로젝트를 표현할 수 있어야 합니다.
프로젝트는 다음 정보를 가집니다.
- 프로젝트 이름
- 여러 모듈
- 여러 모듈 의존 관계
다음 조건을 만족해야 합니다.
- 프로젝트 이름은 비어 있을 수 없습니다.
- 프로젝트 이름은 생성된 뒤 임의로 변경할 수 없어야 합니다.
- 보관 가능한 모듈과 의존 관계의 최대 개수를 정할 수 있어야 합니다.
- 외부 코드가 프로젝트 내부 배열과 저장 개수를 임의로 변경할 수 없어야 합니다.
각 모듈은 이름과 담당 계층을 가집니다.
사용할 계층:
API
APPLICATION
DOMAIN
INFRASTRUCTURE
다음 조건을 만족해야 합니다.
- 모듈 이름은 비어 있을 수 없습니다.
- 같은 프로젝트에 동일한 이름의 모듈을 중복 등록할 수 없습니다.
- 등록 이후 외부 코드가 이름과 계층을 임의로 바꿀 수 없어야 합니다.
- 최대 저장 개수를 초과하지 않도록 처리해야 합니다.
의존 관계는 의존하는 모듈과 의존 대상 모듈을 구분합니다.
api → application
위 표현은 api가 application에 의존한다는 뜻입니다.
다음 조건을 만족해야 합니다.
- 프로젝트에 등록된 모듈 사이에서만 의존 관계를 만들 수 있습니다.
- 하나의 모듈이 자기 자신에게 의존할 수 없습니다.
- 등록 이후 외부 코드가 관계를 임의로 변경할 수 없어야 합니다.
- 최대 저장 개수를 초과하지 않도록 처리해야 합니다.
다음 방향은 허용합니다.
API → APPLICATION
APPLICATION → DOMAIN
INFRASTRUCTURE → DOMAIN
다음 방향은 허용하지 않습니다.
DOMAIN → APPLICATION
DOMAIN → INFRASTRUCTURE
APPLICATION → API
명시되지 않은 방향을 허용할지는 직접 결정하고 그 이유를 학습 기록에 남기세요.
허용 예시:
api
application
order-domain
payment-api
허용하지 않는 예시:
OrderAPI
order_domain
PAYMENT
최소 규칙:
- 영문 소문자를 사용할 수 있습니다.
- 단어 구분에는 하이픈을 사용할 수 있습니다.
- 대문자와 밑줄은 허용하지 않습니다.
- 이름의 처음과 마지막에는 하이픈이 올 수 없습니다.
계층 의존성 규칙과 모듈 이름 규칙을 한 번의 실행으로 검사해야 합니다.
- 서로 다른 규칙을 하나의 배열에 보관할 수 있어야 합니다.
- 배열에 등록된 규칙을 같은 방식으로 실행해야 합니다.
- 실행 부분이 각 규칙의 구체적인 내부 구현을 알 필요가 없어야 합니다.
- 새로운 규칙을 추가할 때 기존 실행 흐름의 변경을 최소화해야 합니다.
각 검사 결과에는 최소한 다음 정보가 있어야 합니다.
- 규칙 이름
- 성공 또는 실패
- 사용자가 이해할 수 있는 메시지
전체 결과에는 최소한 다음 정보가 있어야 합니다.
- 프로젝트 이름
- 실행한 규칙 수
- 성공한 규칙 수
- 실패한 규칙 수
- 각 규칙의 상세 결과
프로그램이 실행되는 동안 전체 검사가 몇 번 수행됐는지 확인할 수 있어야 합니다.
검사를 수행하는 객체가 여러 개 만들어지더라도 하나의 전체 횟수로 집계되어야 합니다.
강의를 모두 들은 뒤 한 번에 완성하지 말고 진도에 맞춰 개선합니다.
- 프로젝트, 모듈, 의존 관계를 데이터로 표현합니다.
- 객체 배열로 여러 모듈과 의존 관계를 저장합니다.
- 코드에서 직접 생성한 데이터를 출력합니다.
- 이 단계에서는 필드에 직접 접근해도 됩니다.
확인 질문:
- 클래스와 객체는 어떻게 다른가요?
- 같은 클래스로 만든 객체들은 상태를 공유하나요?
- 객체 배열에는 무엇이 저장되나요?
다음 상황을 코드로 실험하고 실행 전에 결과를 예상합니다.
- 하나의 객체를 두 변수가 참조하는 경우
- 한 변수를 통해 객체 상태를 변경하는 경우
- 기본형을 메서드에 전달하는 경우
- 객체를 메서드에 전달하는 경우
- 배열의 객체를 메서드에 전달하는 경우
- null인 참조를 통해 객체에 접근하는 경우
- 프로젝트와 관련된 동작을 적절한 객체에 배치합니다.
- 객체 생성 시 필수 정보가 준비되게 합니다.
- 생성 직후 사용할 수 없는 객체가 생기지 않게 합니다.
- 데이터 관리와 출력 책임을 구분합니다.
- 관련 클래스를 패키지로 구분합니다.
- 외부에서 직접 변경하면 안 되는 상태를 숨깁니다.
- 필요한 기능만 외부에 공개합니다.
- 모든 필드에 무조건 getter와 setter를 만들지 않습니다.
- 인스턴스별 상태와 전체 공유 상태를 구분합니다.
- 전체 검사 횟수를 공유합니다.
- 생성 후 변경되지 않아야 하는 값에 제약을 적용합니다.
- 공통 상수를 최소 하나 정의합니다.
공통 속성과 기능을 가진 대상을 찾아 상속 관계를 한 번 적용합니다.
- 부모와 자식 타입을 구분할 수 있어야 합니다.
- 부모가 제공한 공통 기능을 자식이 사용할 수 있어야 합니다.
- 자식이 부모 동작을 재정의하는 사례가 있어야 합니다.
- 부모 생성자와 자식 생성자의 호출 관계를 확인합니다.
상속이 적합하지 않은 곳에는 억지로 적용하지 마세요. 적용한 이유와 다른 방법을 학습 기록에 남깁니다.
- 서로 다른 규칙 구현을 하나의 역할로 다룹니다.
- 하나의 타입 배열에 여러 구현 객체를 보관합니다.
- 실제 객체에 맞는 재정의 메서드가 실행되어야 합니다.
- 규칙 종류마다 조건문으로 실행을 분기하지 않습니다.
- 새 규칙을 추가하고 기존 실행 흐름의 변경 범위를 확인합니다.
모듈:
api, application, domain, infrastructure
의존 관계:
API → APPLICATION
APPLICATION → DOMAIN
INFRASTRUCTURE → DOMAIN
기대 결과:
- 계층 의존성 검사 성공
- 모듈 이름 검사 성공
- 전체 실패 수 0
다음 관계를 포함합니다.
DOMAIN → INFRASTRUCTURE
기대 결과:
- 계층 의존성 검사 실패
- 위반한 관계와 실패 이유 출력
잘못된 이름과 잘못된 의존 방향을 함께 포함합니다.
기대 결과:
- 이름 규칙 실패
- 계층 의존성 규칙 실패
- 두 실패가 전체 결과에 모두 포함됨
기본 기능이 완성되면 다음 요구사항을 추가합니다.
모듈이 자기 자신에게 의존하는 관계가 없는지 검사하는 새로운 규칙을 추가하세요.
확인할 내용:
- 기존 검사 실행 흐름의 변경을 최소화했나요?
- 새 규칙도 기존 규칙과 같은 방식으로 실행되나요?
- 새 결과가 전체 결과에 포함되나요?
완성 후 10분 이내로 다음 내용을 설명합니다.
- 프로그램이 해결하는 문제
- 정상·실패 실행 결과
- 주요 객체의 관계
- 객체 배열을 사용한 위치
- 캡슐화를 적용한 위치와 이유
- static과 final을 사용한 이유
- 상속을 적용한 위치와 다른 선택지
- 다형성을 적용한 위치
- 역할과 구현을 분리한 이유
- 새 규칙을 추가할 때 변경되는 코드
- 프로그램이 컴파일되고 실행된다.
- 여러 모듈과 의존 관계를 배열에 저장한다.
- 중복 모듈과 잘못된 의존 관계를 막는다.
- 계층 의존성과 이름 규칙을 검사한다.
- 세 가지 필수 시나리오를 구분해 출력한다.
- 중요한 상태를 외부에서 직접 변경할 수 없다.
- 인스턴스 상태와 공유 상태를 구분한다.
- 변경되면 안 되는 값에 적절한 제약을 적용한다.
- 상속과 메서드 재정의를 적용한 사례가 있다.
- 여러 규칙 구현을 다형적으로 실행한다.
- 자기 참조 검사 규칙을 추가했다.
- 학습 기록을 자신의 언어로 작성했다.
- 10분 안에 프로그램과 설계를 설명할 수 있다.
- Java 소스 코드
- 작성한
LEARNING_LOG.md - 정상 및 실패 시나리오 실행 결과
- 단계별 커밋 기록