-
Notifications
You must be signed in to change notification settings - Fork 5
3주차 미션 구현 완료 (김세훈) #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
110778c
48f7baa
173033d
8a2b2ef
7d64c49
5f943f7
55a23c7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1,18 @@ | ||
| # All-rounder Backend Study | ||
|
|
||
| 숫자를 입력하면 아스키 아트 형태로 출력하는 Java 기반 CLI 프린터 프로그램임 | ||
| 잉크 잔량을 관리하고, 출력 중 잉크 부족 시 자동으로 중단되며, 다양한 예외 상황을 정교하게 처리함 | ||
|
|
||
| --- | ||
|
|
||
| ## 주요 기능 | ||
|
|
||
| | 기능 | 설명 | | ||
| |------|------| | ||
| | 숫자 출력 | 입력된 숫자(0~9)를 아스키 아트로 출력함 | | ||
| | 용지 크기 설정 | 한 줄에 출력할 문자 개수를 지정할 수 있음 | | ||
| | 잉크 잔량 확인 | 현재 잉크 상태(최대 1000)를 확인할 수 있음 | | ||
| | 잉크 리필 | 출력 도중 언제든지 잉크를 다시 채울 수 있음 | | ||
| | 예외 처리 | 입력 오류, 잉크 부족, 파일 로딩 실패 등을 명확한 메시지로 안내함 | | ||
|
|
||
| ---- |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,15 @@ | ||
| package mission; | ||
|
|
||
| import mission.controller.printerController; | ||
| import mission.model.ink; | ||
| import mission.utils.AsciiGenerator; | ||
| import mission.view.printerView; | ||
|
|
||
| public class Application { | ||
| public static void main(String[] args) { | ||
| //Todo: 프로그램 구현 | ||
| printerController controller = new printerController( | ||
| new AsciiGenerator(), new ink(), new printerView() | ||
| ); | ||
| controller.run(); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,112 @@ | ||
| package mission.controller; | ||
|
|
||
| import mission.model.ink; | ||
| import mission.utils.AsciiGenerator; | ||
| import mission.view.printerView; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.HashMap; | ||
| import java.util.List; | ||
| import java.util.Map; | ||
|
|
||
| public class printerController { | ||
| private final AsciiGenerator generator; | ||
| private final ink inkManager; | ||
| private final printerView view; | ||
| private static final int LINE_COUNT = 5; | ||
| private final Map<String, Runnable> menuMap = new HashMap<>(); | ||
|
|
||
| public printerController(AsciiGenerator generator, ink inkManager, printerView view) { | ||
| this.generator = generator; | ||
| this.inkManager = inkManager; | ||
| this.view = view; | ||
| initMenu(); | ||
| } | ||
|
|
||
| public void run() { | ||
| while (true) { | ||
| view.printMenu(); | ||
| String input = view.input(""); | ||
| if (input.equals("4")) return; | ||
| Runnable action = menuMap.get(input); | ||
| if (action != null) action.run(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. runnable을 선언할 필요 없이 바로 실행하는 편이 가독성이나 효율성 측면에서 더 좋을 것 같아요 |
||
| } | ||
| } | ||
|
|
||
| private void initMenu() { | ||
| menuMap.put("1", this::handlePrint); | ||
| menuMap.put("2", this::handleInkCheck); | ||
| menuMap.put("3", this::handleInkRefill); | ||
| } | ||
|
|
||
| private void handlePrint() { | ||
| String text = view.input("출력할 문자를 입력해주세요. "); | ||
| int size = view.paperSize("용지 크기를 입력해주세요. "); | ||
| printAsciiHorizontally(text, size); | ||
| view.showMessage("출력이 완료되었습니다. "); | ||
| } | ||
|
|
||
| private void handleInkCheck() { | ||
| int amount = inkManager.getInk(); | ||
| view.showMessage(String.format("잉크 잔량 : %d/1000", amount)); | ||
| } | ||
|
|
||
| private void handleInkRefill() { | ||
| inkManager.refillInk(); | ||
| view.showMessage("잉크를 교체하였습니다. "); | ||
| } | ||
|
|
||
| public void printAsciiHorizontally(String input, int paperSize) { | ||
| int start = 0; | ||
| while (start < input.length()) { | ||
| int end = Math.min(start + paperSize, input.length()); | ||
| printOneLine(input.substring(start, end)); | ||
| start = end; | ||
| } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. reduce를 써서 함수형 프로그래밍으로 표현할 수 있지 않을까요? |
||
| } | ||
|
|
||
| private void printOneLine(String input) { | ||
| List<StringBuilder> lines = initLines(); | ||
| try { | ||
| buildAsciiLines(input, lines); | ||
| printLines(lines); | ||
| } catch (IllegalStateException e) { | ||
| view.showMessage(e.getMessage()); | ||
| } | ||
| } | ||
|
|
||
| private void buildAsciiLines(String input, List<StringBuilder> lines) { | ||
| for (char ch : input.toCharArray()) { | ||
| if (ch == ' ') { | ||
| appendSpace(lines); | ||
| continue; | ||
| } | ||
| inkManager.minusInk(); | ||
| appendAscii(lines, ch); | ||
| } | ||
| } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 부분도 stream API를 사용하면 더 효율적이고 가독성 높게 구성할 수 있을 것 같아요 |
||
|
|
||
| private List<StringBuilder> initLines() { | ||
| List<StringBuilder> lines = new ArrayList<>(); | ||
| for (int i = 0; i < LINE_COUNT; i++) lines.add(new StringBuilder()); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 부분이랑 아래 부분들을 함수형으로 구성하면 좋을 것 같아요 |
||
| return lines; | ||
| } | ||
|
|
||
| private void appendAscii(List<StringBuilder> lines, char ch) { | ||
| int num = Character.getNumericValue(ch); | ||
| List<String> ascii = generator.getNumberAsciiDesign(num); | ||
| for (int i = 0; i < ascii.size(); i++) { | ||
| lines.get(i).append(String.format("%s ", ascii.get(i))); | ||
| } | ||
| } | ||
|
|
||
| private void appendSpace(List<StringBuilder> lines) { | ||
| for (int i = 0; i < LINE_COUNT; i++) { | ||
| lines.get(i).append(String.format("%s ", " ")); | ||
| } | ||
| } | ||
|
|
||
| private void printLines(List<StringBuilder> lines) { | ||
| for (StringBuilder line : lines) System.out.println(line); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| package mission.model; | ||
|
|
||
| public class ink { | ||
| private int ink = 1000; | ||
|
|
||
| public int getInk() { | ||
| return ink; | ||
| } | ||
|
|
||
| public void minusInk() { | ||
|
|
||
| if (ink <= 0) { | ||
| throw new IllegalStateException("[ERROR] 잉크가 부족해 출력을 중단합니다."); | ||
| } | ||
| this.ink -= 1; | ||
|
|
||
| } | ||
|
|
||
| public void refillInk() { | ||
| this.ink = 1000; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| package mission.view; | ||
|
|
||
| import java.util.Scanner; | ||
|
|
||
| public class printerView { | ||
| private final Scanner scanner = new Scanner(System.in); | ||
|
|
||
| public void printMenu(){ | ||
| System.out.println("프린터를 실행합니다."); | ||
| System.out.print("사용할 기능을 입력해주세요. 1) 출력, 2) 잉크 잔량 확인, 3) 잉크 교체, 4) 프로그램 종료"); | ||
| } | ||
|
|
||
| public String input(String message){ | ||
| System.out.println(message); | ||
| return scanner.nextLine(); | ||
| } | ||
|
|
||
| public void showMessage(String message){ | ||
| System.out.println(message); | ||
| } | ||
|
|
||
| public int paperSize(String message){ | ||
| System.out.println(message); | ||
| int value = scanner.nextInt(); | ||
| scanner.nextLine(); // 버퍼에 남아있는 \n 제거 | ||
| return value; | ||
| } | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| package mission; | ||
|
|
||
| import mission.model.ink; | ||
| import org.junit.jupiter.api.Test; | ||
|
|
||
| import static org.junit.jupiter.api.Assertions.*; | ||
|
|
||
| class InkTest { | ||
|
|
||
| @Test | ||
| void initial_ink_amount_should_be_1000() { | ||
| ink testInk = new ink(); | ||
| assertEquals(1000, testInk.getInk()); | ||
| } | ||
|
|
||
| @Test | ||
| void ink_decreases_by_1_per_print() { | ||
| ink testInk = new ink(); | ||
| testInk.minusInk(); | ||
| assertEquals(999, testInk.getInk()); | ||
| } | ||
|
|
||
| @Test | ||
| void exception_thrown_when_ink_is_empty() { | ||
| ink testInk = new ink(); | ||
| for (int i = 0; i < 1000; i++) testInk.minusInk(); | ||
| IllegalStateException e = assertThrows(IllegalStateException.class, testInk::minusInk); | ||
| assertTrue(e.getMessage().contains("[ERROR] 잉크가 부족해 출력을 중단합니다.")); | ||
| } | ||
|
|
||
| @Test | ||
| void refill_restores_ink_to_1000() { | ||
| ink testInk = new ink(); | ||
| testInk.minusInk(); | ||
| testInk.refillInk(); | ||
| assertEquals(1000, testInk.getInk()); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
클래스명은 대문자로 시작하는게 컨벤션상 좋을거같아요