DevLog ๐ถ
[์ฐํ ์ฝ 5๊ธฐ] ์ฌ๋ค๋ฆฌ ํ๊ธฐ ๊ฒ์ ๋ฏธ์ ํ๊ณ ๋ณธ๋ฌธ
[์ฐํ ์ฝ 5๊ธฐ] ์ฌ๋ค๋ฆฌ ํ๊ธฐ ๊ฒ์ ๋ฏธ์ ํ๊ณ
dolmeng2 2023. 4. 3. 14:12ํ์ถ๋ ์งํํ ๋ ๋ฒ์งธ ํ์ด ํ๋ก๊ทธ๋๋ฐ์ธ ์ฌ๋ค๋ฆฌ ๋ฏธ์
์ด๋ค.
์ฌ์ค ์ด๋ฒ ๋ฏธ์
์ ๊ต์ฅํ ๋นจ๋ฆฌ merge๊ฐ ๋์ด์ ๋ฏธ์
์์ฒด์ ๋ง์ด ์ ๊ฒฝ์ ์ฐ์ง๋ ์์๋ ๊ฒ ๊ฐ์๋ฐ, ๋ค๋ฅธ ํฌ๋ฃจ๋ถ๋ค์ด ๊ณ ๋ฏผํ์๋ ๊ฑธ ๋ณด๊ณ ์์ผ๋ ๋ด๊ฐ ๋๋ฌด ์๊ฐ์ ์ ํ ๊ฒ์ธ๊ฐ... ๋ผ๋ ์๊ฐ์ด ๋ค์๋ค ๐ฆ ๋ค์ ๋ฏธ์
์์๋ ์กฐ๊ธ ๋ ์ ๊ฒฝ์ฐ๋ฉด์ ์งํํด์ผ ํ ๊ฒ ๊ฐ๋ค.
๊ทธ๋๋ ํ์ถ ๋๋ถ์ ๋๋ฉ์ธ ์ค๊ณ๋ฅผ ๊ต์ฅํ ์์ํ๊ฒ ํด์, ๋ ๋น ๋ฅด๊ฒ ๋ง๋ฌด๋ฆฌ ํ ์ ์์๋ ์๊ฐ์ธ ๊ฒ ๊ฐ๋ค.
(๋ฌผ๋ก ... ์ด ๊ฒ์๊ธ์ ์์ฑํ ์์ ์์๋ ํ์ฐธ ์ ์ ๋๋ ๋ฏธ์
์ด์ง๋ง, ์์ ์ ์ฅ์ ํด๋๊ณ ์ฌ๋ฆฌ์ง ์์์ด์...ใ
๋ค๋ฆ๊ฒ ์ฌ๋ฆฐ๋ค)
โ๏ธ ์์ฑํ ์ฝ๋
โ๏ธ 1์ฐจ PR
โ๏ธ 2์ฐจ PR
โ๏ธ ๊ธฐ๋ฅ ์๊ตฌ์ฌํญ
- ์ฌ๋ค๋ฆฌ ๊ฒ์์ ์ฐธ์ฌํ๋ ์ฌ๋์ ์ด๋ฆ์ ์ต๋ 5๊ธ์๊น์ง ๋ถ์ฌํ ์ ์๋ค.
- ์ฌ๋ค๋ฆฌ๋ฅผ ์ถ๋ ฅํ ๋ ์ฌ๋ ์ด๋ฆ๋ ๊ฐ์ด ์ถ๋ ฅํ๋ค.
- ์ฌ๋ ์ด๋ฆ์ ์ผํ(,)๋ฅผ ๊ธฐ์ค์ผ๋ก ๊ตฌ๋ถํ๋ค.
- ์ฌ๋ ์ด๋ฆ์ 5์ ๊ธฐ์ค์ผ๋ก ์ถ๋ ฅํ๊ธฐ ๋๋ฌธ์ ์ฌ๋ค๋ฆฌ ํญ๋ ๋์ด์ ธ์ผ ํ๋ค.
- ์ฌ๋ค๋ฆฌ ํ๊ธฐ๊ฐ ์ ์์ ์ผ๋ก ๋์ํ๋ ค๋ฉด ๋ผ์ธ์ด ๊ฒน์น์ง ์๋๋ก ํด์ผ ํ๋ค.
- |-----|-----| ๋ชจ์๊ณผ ๊ฐ์ด ๊ฐ๋ก ๋ผ์ธ์ด ๊ฒน์น๋ ๊ฒฝ์ฐ ์ด๋ ๋ฐฉํฅ์ผ๋ก ์ด๋ํ ์ง ๊ฒฐ์ ํ ์ ์๋ค.
- ์ฌ๋ค๋ฆฌ ์คํ ๊ฒฐ๊ณผ๋ฅผ ์ถ๋ ฅํด์ผ ํ๋ค.
- ๊ฐ์ธ๋ณ ์ด๋ฆ์ ์
๋ ฅํ๋ฉด ๊ฐ์ธ๋ณ ๊ฒฐ๊ณผ๋ฅผ ์ถ๋ ฅํ๊ณ , "all"์ ์
๋ ฅํ๋ฉด ์ ์ฒด ์ฐธ์ฌ์์ ์คํ ๊ฒฐ๊ณผ๋ฅผ ์ถ๋ ฅํ๋ค.
PR ๋ด์ฉ ์ค์์ ๋ช ๊ฐ์ง ์ธ์ ๊น์๋ ๋ด์ฉ์ ์ ์ด๋ณด๋ ค๊ณ ํ๋ค.
๐ฌ ์ฌ๋ค๋ฆฌ๋ ์์ ํ ๋๋คํ๊ฒ ์์ฑ๋์ด์ผ ํ ๊น?
์ฌ๋ค๋ฆฌ ๊ฒ์์์ ์ฌ๋ค๋ฆฌ๊ฐ ๋๋ค์ผ๋ก ์์ฑ๋๋ ๊ฒ ์ค์ํ ๊น? ์ฌ์ค ํ์ด ํ๋ก๊ทธ๋๋ฐ์ ํ๊ธฐ ์ ์๋ ์ ํ ๊ณ ๋ คํ์ง ์์์ ์ฌํญ์ด์ง๋ง, ํ์ถ๊ฐ ์๋ฌธ์ ์ ๊ธฐํด ์ฃผ์๋ค. ๋ฃ๊ณ ๋ณด๋ ์ฌ๋ค๋ฆฌ ๊ฒ์์์ ์ด๋ ๋ผ์ธ์ ๊ณ ๋ฅด๋ ๋์ผํ ํ๋ฅ ๋ก ๋ค๋ฅธ ๊ณณ์ ๋๋ฌํด์ผ ๋๋ค๊ณ ์๊ฐํ๊ธฐ ๋๋ฌธ์ด๋ค. ๊ทธ๋ฌ๋, ์ด ์กฐ๊ฑด์ ๋ง์กฑํ๊ธฐ ์ํด์๋ ๋๋ฌด ๋ณต์กํ ๋ก์ง์ด ๋ค์ด๊ฐ์ผ ํ๋ค.
๋ฆฌ๋ทฐ์ด๋๊ป ๋ฐ๋ก ๋ฌผ์ด๋ณธ ๊ฒฐ๊ณผ, ์ฌ๋ค๋ฆฌ ๊ฒ์์์ ๊ณผ์ฐ ๊ทธ๊ฒ ์ค์ํ ๊ฒ์ธ๊ฐ?๋ฅผ ๋ฐ์ ธ๋ณด๋ผ๊ณ ํ์
จ๋ค. ์ฌ์ค ๊ฒ์์์ ๊ฐ์ฅ ์ค์ํ ๊ฒ์ ์์์ง์์ ๋ค๋ฅธ ๋์ฐฉ์ง๋ก ๊ฐ๋ ๊ฒ์ด ์ค์ํ ๊ฑฐ์์ผ๋๊น. ๋์์ ๋ค์๊ณผ ๊ฐ์ ์์์ ์ฃผ์
จ๋๋ฐ, ์ ์ด๋ถํฐ ์ฌ๋ค๋ฆฌ ๊ฒ์์ ๋ถ๊ณตํํ๋ค๊ณ ํ๋ค ใ
ใ
๐ฌ Scanner vs BufferedReader
private String readConsole() {
try {
return bufferedReader.readLine();
} catch (IOException e) {
OutputView.print(e.getMessage());
}
return null;
}
์ฌ์ฉ์์๊ฒ ์
๋ ฅ๋ฐ์ ๋ ์ BufferedReader๋ฅผ ์ฌ์ฉํ๋์ง์ ๋ํ ์ง๋ฌธ์ ๋ค์์๋ค. ์ฌ์ค, ๋๋ ์ฝ๋ฉ ํ
์คํธ๋ฅผ ํ๋ฉด์ ์ฑ๋ฅ์ ์ ๋ํ ์ ๊ฒฝ์ฐ๋ค ๋ณด๋๊น Scanner๋ณด๋ค BufferedReader๋ฅผ ์ผ์ข
์ ์ต๊ด์ฒ๋ผ ์ฌ์ฉํ์๋๋ฐ, ์ ์ฑ๋ฅ์ด ๋ ์ข์์ง ์ ๋๋ก ์ฐพ์๋ณธ ์ ์ด ์์๋ค. ๊ทธ๋์ ์ด๋ฒ ๊ธฐํ์ ๊ถ๊ธํด์ ์ฐพ์๋ณด์๋ค.
Scanner์ ๊ฒฝ์ฐ, ๋ฐ์ดํฐ๋ฅผ ์
๋ ฅ๋ฐ์ ์ฆ์ ์ฌ์ฉ์์๊ฒ ์ ์กํ๋ฉฐ, ๋ด๋ถ์์ ์ ๊ท์์ ์ฌ์ฉํ๋ค ๋ณด๋ ์๊ฐ์ด ๋ ๊ฑธ๋ฆฌ๊ณ , BufferedReader์ ๊ฒฝ์ฐ ์ฌ์ฉ์์๊ฒ ๋ฐ๋ก ์ ์กํ์ง ์๊ณ , ๋ฒํผ์ ์ ์ฅํด๋์๋ค๊ฐ ๊ฐํ์ด๋ ๊ฐ๋ ์ฐผ์ ๊ฒฝ์ฐ ์ฌ์ฉ์์๊ฒ ์ ๋ฌํ์ฌ ์ฒ๋ฆฌ ์๊ฐ์ด ๋ ์ ๊ฒ ๊ฑธ๋ฆฐ๋ค. ๊ทธ ์ธ์๋ ์์ธ ์ฒ๋ฆฌ๋ฅผ ์งํํด์ค์ผ ํ๋ค๋ ์ , ๋ณ๋์ ํ์
์ ๋ฐ๋ฅธ ํ์ฑ์ด ํ์ํ๋ค๋ ์ ์ด ์๋ค.
๋ฆฌ๋ทฐ์ด๋์ด ์ง์ ํ
์คํธ๋ ์งํํด ์ฃผ์
จ๋๋ฐ, ๋ค์๊ณผ ๊ฐ์ด ๊ฒฐ๊ณผ๊ฐ ๋์๋ค!
ํ์คํ ์ฑ๋ฅ์ ์ผ๋ก๋ ์ข์ง๋ง, ์ฌ์ค ์ด๋ฒ ๋ฏธ์ ์์๋ ์คํ๋ ค ๋ ์ด ๋์์ ์๋ ์๋ค. ๋ช ์์ ์ผ๋ก try-catch๋ฅผ ํตํด์ IoException์ ์ก์์ผ ํ๊ธฐ ๋๋ฌธ์ ์คํ๋ ค ์ฝ๋๊ฐ ๋ ์ ์์๊ฒ ๋ณด์ผ ์๋ ์์๋ค๋ ์ ์ด๋ค. ํ์ง๋ง, ๊ฐ์ธ์ ์ผ๋ก๋ ์ฑ๋ฅ์ ์กฐ๊ธ ๋ ์ค์์ํ๋ ์ ์ฅ์์ ๋ฆฌ๋ทฐ์ด๋๊ป ๋ค์๊ณผ ๊ฐ์ด ๋ง์๋๋ ธ๋ค.
๋์ถฉ checked Exception์ unchecked Exception์ผ๋ก ๊ฐ์ธ๋ ๊ฑธ ์ ํธํ๋ค๋ ์ด์ผ๊ธฐ... ์๋ฌดํผ, ๊ทธ๋์ ๋ฆฌํฉํฐ๋ง์ ์งํํ์ง ์์์ง๋ง ์ด๋ฒ ๊ธฐํ์ ์๋กญ๊ฒ ์์๊ฐ ์ ์์์ด์ ๋์์ด ๋์๋ค.
๐ฌ ์ ๋ณด์ ๋ฌธ๊ฐ ํจํด
์ด๊ฒ๋ ๋ฆฌ๋ทฐ์ด๋์ด ์ฃผ์
จ๋ ๋ ํผ๋ฐ์ค ์ค ํ๋์ด๋ค. ์ด๋ ํ ํ์์ ๋ํด์, ๊ฐ์ฅ ๊ทธ ํ์๋ฅผ ์ํ ๊ฒ ๊ฐ์ ๊ฐ์ฒด์๊ฒ ์์ํ๋ ๊ฒ์ด๋ค!
์ด ์์ ์์ ๋๋ ์ฌ์ฉ์์๊ฒ ์
๋ ฅ๋ฐ๋ ๋ถ๋ถ์ ๋ํด, ๋ทฐ์ ์ปจํธ๋กค๋ฌ๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ๊ตฌ์ฑํ์๋ค.
public class InputView {
private final BufferedReader bufferedReader;
public InputView() {
this.bufferedReader = new BufferedReader(new InputStreamReader(System.in));
}
public String readConsole() {
try {
return bufferedReader.readLine();
} catch (IOException e) {
OutputView.print(e.getMessage());
}
return null;
}
public <T> T getUserInput(Supplier<T> inputReader) {
try {
return inputReader.get();
} catch (IllegalArgumentException e) {
OutputView.print(e.getMessage());
return getUserInput(inputReader);
}
}
}
// Controller
private Participants createParticipants() {
return inputView.getUserInput(() -> {
OutputView.print(INPUT_PARTICIPANT_NAMES_GUIDE.getMessage());
String participantNames = inputView.readConsole();
return Participants.create(participantNames);
});
}
์
๋ ฅํ๋ ์๋ด ๋ฉ์์ง๋ฅผ ์ปจํธ๋กค๋ฌ์์ ๋ณด์ฌ์ฃผ๊ณ , ๋จ์ํ ๋ทฐ์์๋ ์
๋ ฅ๋ง ๋ฐ์๋ ๊ฒ์ด๋ค. ์ฌ์ค ๋ทฐ์ ๋ฉ์๋๋ฅผ ์ฌ์ฌ์ฉํ ์ ์์๊ธฐ ๋๋ฌธ์ ์์ ๊ฐ์ ๋ฐฉ์์ ์งํํ์์ง๋ง, ์ ๋ณด ์ ๋ฌธ๊ฐ ํจํด์ ๊ด์ ์ผ๋ก ๋ฐ๋ผ๋ณด์์ ๋๋ ๋ค๋ฅธ ๊ฐ๋ฐ์๊ฐ '์ฌ์ฉ์์๊ฒ ์๋ด ๋ฉ์์ง๋ฅผ ์ถ๋ ฅํ๊ณ , ๋ฉ์์ง๋ฅผ ์
๋ ฅ๋ฐ๋ ๊ธฐ๋ฅ์ ๋ํด ์ด๋ ํจํค์ง๋ฅผ ๋จผ์ ์ด์ด๋ณผ ๊ฒ์ธ๊ฐ?'๋ผ๊ณ ๋ฐ์ ธ๋ณด๋ฉด ์ข์ ๊ตฌ์กฐ๋ ์๋๋ค. InputView๋ฅผ ๋จผ์ ๋ณด๋ ๊ฐ๋ฐ์๋ค๋ ๋ถ๋ช
์กด์ฌํ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ด๋ค.
๊ทธ๋์, ๋ค์๊ณผ ๊ฐ์ด ๋ฆฌํฉํฐ๋ง์ ์งํํ๋ค.
public String getParticipantNames() {
OutputView.print(INPUT_PARTICIPANT_NAMES_GUIDE.getMessage());
return readConsole();
}
// Controller
private Participants createParticipants() {
return inputView.getInputWithRetry(() -> {
String participantNames = inputView.getParticipantNames();
return Participants.create(participantNames);
});
}
์ด๋ ๊ฒ ๋๋ฉด ์ ๋ ฅ๋ฐ๋ ๊ธฐ๋ฅ์ ๋ฐ๋ผ ๋ฉ์๋๊ฐ ๋์ด๋๋ค๋ ์ ์ด ์์ง๋ง, 'ํด๋น ํ์๊ฐ ์ด๋์ ์ฑ ์์ธ๊ฐ?'์ ๊ด์ ์์ ๋ณด์์ ๋, ์ฌ์ฉ์์๊ฒ ๋ฉ์์ง๋ฅผ ์ถ๋ ฅํ๊ณ ์ ๋ ฅ๋ฐ๋ ๊ธฐ๋ฅ๊น์ง ๋ทฐ๊ฐ ๋ด๋นํ๊ฒ ๋์ด ์ฑ ์ ๋ถ๋ฆฌ๋ฅผ ์ ํ ๊ฒ ๊ฐ๋ค๋ ์๊ฐ์ด ๋ ๋ค.
๐ฌ ์ฌ๋ค๋ฆฌ ์์ฑ ๋ก์ง
๋น์์๋ ์ค๋ฒ ์์ง๋์ด๋ง์ ๋ฌด์ฒ ์ ๊ฒฝ์ฐ๊ณ ์์๋ค. ์์
์ ๋ค์ผ๋ฉด์ ์ค๋ฒ ์์ง๋์ด๋ง์ ์คํ๋ ค ์
์ํฅ์ด๋ผ๋ ์๊ฐ์ ๋ง์ด ํ๊ธฐ ๋๋ฌธ์ด๋ค. ํ์ง๋ง, OCP๋ฅผ ์งํค๊ธฐ ์ํด CBP์ ๋ํด ๋ฆฌ๋ทฐ์ด๋์ด ๋ง์ํด ์ฃผ์
จ๋ค :D ๋ชจ๋ ํ์ฅ์ฑ์ ๋ํด์ ๊ณ ๋ คํ๊ธฐ๋ ํ๋ค๋ค๋ ๊ฒ์ด๋ค. ๋์์ ์ ๋๋ ์ดํฐ์ ๋ํด์๋ ๋ง์ํด ์ฃผ์
จ๋๋ฐ, ์ด๋ ์๋์ ํ์ ํ๊ฒ ๋ค.
์ฐ์ , ๊ธฐ์กด์ ์ฌ๋ค๋ฆฌ ์์ฑ ๋ก์ง์ด๋ค.
public class Ladder {
private final List<Rungs> ladder;
public Ladder(final List<Rungs> ladder) {
this.ladder = ladder;
}
}
public class LadderFactory {
private static final int MIN_HEIGHT = 1;
private static final int MAX_HEIGHT = 10_000;
private static final int DEFAULT_COUNT = 1;
private final NumberGenerator rungNumberGenerator;
public LadderFactory(final NumberGenerator rungNumberGenerator) {
this.rungNumberGenerator = rungNumberGenerator;
}
public Ladder createLadder(final String height, final int participantCount) {
int ladderHeight = convertLadderHeight(height);
List<Rungs> ladder = new ArrayList<>();
for (int i = 0; i < ladderHeight; i++) {
ladder.add(new Rungs(makeRungCount(participantCount), rungNumberGenerator));
}
return new Ladder(ladder);
}
}
์ฌ๋ค๋ฆฌ์ ์์ฑ ๋ก์ง์ ์ฌ๋ค๋ฆฌ๊ฐ ๊ฐ์ง๋ ๊ฒ์ด ์๋, ๋ณ๋์ ๊ฐ์ฒด์๊ฒ ์ฑ
์์ ํ ๋นํ์๋ค.
์ด๋ ์ฌ๋ค๋ฆฌ๋ฅผ ์์ฑํ๊ธฐ ์ํด ํ์ํ ์๊ตฌ์ฌํญ์ด ๋ณ๊ฒฝ๋ ์๋ ์๋ค๋ ๊ฐ๋
๊ณผ, ์ฌ๋ค๋ฆฌ๋ฅผ ์์ฑํ๋ ๊ท์น ์์ฒด๊ฐ ์๋นํ ๋ณต์กํ๊ธฐ ๋๋ฌธ์ ์ด๋ฅผ ๋ถ๋ฆฌํ๊ณ ์ถ์๋ค. ๋ํ, ์กฐ๊ธ ๋ ๋์ ์ผ๋ก ์์ฑํ๋๋ก ๋ง๋ค๊ณ ์ถ์ด์ height์ participantCount๋ฅผ ๋ณ์๋ก ๊ด๋ฆฌํ์ง ์๊ณ ์ธ์๋ก ๋ฐ์์ ์กฐ๊ฑด์ ๋ง๊ฒ ์ฌ๋ค๋ฆฌ๋ฅผ ์์ฑํ ์ ์๋๋ก ํ๊ณ ์ถ์๋ค.
๊ทธ๋ฌ๋, ์ ์ฝ๋๋ ์น๋ช
์ ์ธ ์ค์๊ฐ ์๋ค. LadderFactory๊ฐ Ladder๋ฅผ ์์ฑํ๊ธฐ ์ํด์ Ladder์ ์์ฑ์๊ฐ ์ด๋ฆฌ๊ฒ ๋๋ ๊ฒ์ด๋ค. ๋น์, ์ฒ์์ผ๋ก ์ฝ๋๋ฅผ ์์ฑํ ๋๋ ์ ๊ทผ์ ์ด์ ๋ง์ ๋ public์ผ๋ก ์ด์ด์ ์ธ๋ถ์์ Ladder๋ฅผ ํตํด '์ฌ๋ค๋ฆฌ'๋ผ๋ ๊ฐ์ฒด๋ฅผ ๋ง๋ค ์ํ์ฑ๋ ์กด์ฌํ๊ฒ ๋ ๊ฒ์ด๋ค.
๋น์ ๋ฆฌ๋ทฐ์ด๋๊ป ๋ฐ์๋ ํผ๋๋ฐฑ์ด๋ค. ๋๋ LadderFactory๋ฅผ ํตํด์ Ladder๋ฅผ ์์ฑํ๊ธฐ ์ํ์ง๋ง, ๋ค๋ฅธ ๊ฐ๋ฐ์๋ ๊ทธ๊ฑธ ์ ํฑ์ด ์๋ ๊ฒ์ด๋ค. ํ์ง๋ง ์ฃผ์์ ํตํด ์ด๋ฌํ ์ธ๋ถ ๊ณ์ฝ์ ๊ด๋ฆฌํ๋ ๊ฒ์ ์ข์ง ์๋ค. ๊ทธ๋์ ์ฒ์์๋ Ladder์ ์์ฑ์๋ฅผ default ์ ๊ทผ ์ ์ด์๋ก ๋ง๋ ์์ผ๋ก ๊ตฌํํ์๋ค.
ํ์ง๋ง... ์ฌ์ค ์ ๊ทผ ์ ์ด์๋ ๊ฒฐ๊ตญ ๊ฐ์ ํจํค์ง ๋ด์์๋ ์์ฑ์ ๋ง์ ์ ์๊ฒ ๋๋ค. ๋ฌผ๋ก , ํจํค์ง ๋ถ๋ฆฌ๋ฅผ ์ํด์ domain ์์ญ - Ladder์ ๊ดํ ์์ญ์ผ๋ก ๋๋๊ณ ์๊ฒฉํ๊ฒ ๊ด๋ฆฌํ๋ฉด ๋๊ฒ ์ง๋ง, ์ด ์ญ์ ๊ฒฐ๊ตญ ๊ฐ๋ฐ์๊ฐ ๊ด๋ฆฌํด์ผ ํ๋ ์ผ์ด๊ณ , ๋ค๋ฅธ ํ์
์๊ฐ ํจํค์ง๋ฅผ ์ด๋ํ๊ธฐ๋ผ๋ ํ๋ค๋ฉด ๊ฒฐ๊ตญ Ladder๋ ๋ค๋ฅธ ๋ฐฉ์์ผ๋ก ์์ฑ๋ ์๋ ์๊ฒ ๋๋ค.
๊ทธ๋ฆผ์ผ๋ก ์๊ฐํ๋ค๋ฉด ํ์ฌ ์ด๋ฐ ๋๋์ธ ๊ฒ์ด๋ค.
๊ทธ๋์...! ๋ฆฌ๋ทฐ์ด๋์ด ์ ๋ง ์ข์ ๋ฐฉ์์ ์ฃผ์
จ๋ค ๐
public class Ladder {
private final List<Rungs> ladderRungs;
private Ladder(final List<Rungs> ladderRungs) {
this.ladderRungs = ladderRungs;
}
public static Ladder create(final String height, final int participantCount, final BooleanGenerator rungGenerator) {
List<Rungs> ladderRungs = LadderRungsFactory
.getInstance(rungGenerator)
.createLadderRungs(height, participantCount);
return new Ladder(ladderRungs);
}
}
public class LadderRungsFactory {
private static final int MIN_HEIGHT = 1;
private static final int MAX_HEIGHT = 10_000;
private static final int DEFAULT_COUNT = 1;
private static final Map<BooleanGenerator, LadderRungsFactory> CACHE = new HashMap<>();
private final BooleanGenerator rungGenerator;
private LadderRungsFactory(final BooleanGenerator rungGenerator) {
this.rungGenerator = rungGenerator;
}
static LadderRungsFactory getInstance(final BooleanGenerator rungGenerator) {
if (CACHE.containsKey(rungGenerator)) {
return CACHE.get(rungGenerator);
}
LadderRungsFactory ladderRungsFactory = new LadderRungsFactory(rungGenerator);
CACHE.put(rungGenerator, ladderRungsFactory);
return ladderRungsFactory;
}
protected List<Rungs> createLadderRungs(final String height, final int participantCount) {
int ladderHeight = convertToLadderHeight(height);
List<Rungs> ladder = new ArrayList<>();
for (int i = 0; i < ladderHeight; i++) {
ladder.add(Rungs.create(makeRungCount(participantCount), rungGenerator));
}
return ladder;
}
๋ฌด์จ ์ฐจ์ด๊ฐ ์๋์ง ๋์ ๋ณด์ด๋๊ฐ? (์บ์๋ ํฉํ ๋ฆฌ ์์ฒด๊ฐ ์ฌ๋ฌ ๋ฒ ์์ฑ๋ ํ์๊ฐ ์๊ธฐ ๋๋ฌธ์ ์ฒ๋ฆฌํด๋์๋ค.)
์ฌ๋ค๋ฆฌ๋ฅผ ์์ฑํ ๋ ๋จ์ํ Ladder ๊ฐ์ฒด๋ฅผ Ladder๊ฐ ํผ์ ์์ฑํ๋ ๊ฒ์ด ์๋, ๋ด๋ถ์ ์ผ๋ก LadderFactory๋ฅผ ํธ์ถํ์ฌ ์์ฑํ๋ ๊ฒ์ด๋ค. ์ ์ด ๋ก์ง์ด Ladder -> LadderFactory -> Ladder๋ก ๋ค์ ์์ํ๋ ๊ตฌ์กฐ๊ฐ ๋๋ ๊ฒ์ด๋ค.
๊ทธ๋ฆผ์ผ๋ก ์ดํด๋ณด์. ์บ์ฑ์ ๋ํ ๋ถ๋ถ์ ์ ์ธํ๊ณ ๋ก์ง์ ๋ค์ ์ธ์ ๋ค.
์ฐ์ , LadderFactory๊ฐ ํ์ํ ๋ณ์์ ๊ฒฝ์ฐ Ladder๊ฐ ๊ฐ์ง๊ฒ ๋๋ค.
Ladder๋ ์ฌ๋ค๋ฆฌ๋ฅผ ์์ฑํ ๋ ๋ด๋ถ์ ์ผ๋ก LadderFactory๋ฅผ ํธ์ถํ์ฌ ์ฌ๋ค๋ฆฌ ์์ฑ์ ํ์ํ ๋ถํ์ธ List<Rungs>๋ฅผ ๋ฐ๊ฒ ๋๊ณ , ๊ฐ์ ํจํค์ง ๋ด์์ LadderFactory์ createLadderRungs๋ฅผ ํธ์ถํ๋๋ผ๋ Ladder ์์ฒด๋ฅผ ์์ฑํ ์ ์๊ธฐ ๋๋ฌธ์ ๊ฒฐ๊ตญ 'Ladder' ์์ฒด๋ฅผ ์์ฑํ๊ธฐ ์ํด์๋ Ladder ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ฒ ๋๋ค.
์ ํด๋ฒ์ ์๊ณ ๋์ ์ ๋ง ํฐ ๊นจ๋ฌ์์ ์ป๊ฒ ๋์๋ค... ์ด๋ ์ถํ ๋์ฌ ์ฒด์ค ๋ฏธ์
์์๋ ์์ฐจ๊ฒ ์จ๋จน์๋ค.
๐ฌ ์์ธ ๋ฉ์์ง ์ฒ๋ฆฌ
์ฌ์ค ์์ธ ๋ฉ์์ง๋ ์ด์ ๋ฏธ์ ์์๋ ๊ณ์ ๊ณ ๋ฏผํด์์๋ค. ์ด์ ๊น์ง๋ ๋ฉ์์ง ์์ฒด๋ฅผ enum์ผ๋ก ๊ด๋ฆฌํ๋ฉด์ ๋ณ๋์ ์์ธ ๋ฉ์์ง์ ๋ํด ํ ๋ฒ์ ๊ด๋ฆฌํ๋๋ก ๋ง๋ค์์๋๋ฐ, ์๋น์ค๊ฐ ์ปค์ง๊ณ ๋๋ฉ์ธ์ด ์ปค์ง๋ค๋ฉด ์ด๋ฐ ์์ผ๋ก ๊ด๋ฆฌํ๋ ๊ฒ ๊ทธ๋ ๊ฒ ์ข์ง ์์ ๊ฒ ๊ฐ๋ค๋ ์๊ฐ์ด ๋ค์๋ค.
public enum ErrorMessage {
AAA("")
...
}
ํ์ง๋ง, ์ด๋ฐ util์ฑ ๊ฐ์ฒด๊ฐ ๊ณผ์ฐ ๊ฐ์ฒด์งํฅ์ ๊ด์ ์์ ์ ์๋ฏธํ ๊ฒ์ธ๊ฐ?๋ฅผ ์๊ฐํด๋ณด์์ผ ํ๋ค.
๋๋ ์ด์ ๊น์ง util ์ฑ ๊ฐ์ฒด์ ๋ํด์ ์๋ฌด ์๊ฐ๋ ์์๋ค. ๊ทธ๋์ ์ด๋ฒ ๊ธฐํ์ ํ ๋ฒ ์๊ฐํด๋ณด์๋ค...
์ด๋ ๊ณณ์์ ์ฐธ์กฐ๊ฐ ๊ฐ๋ฅํ ํด๋์ค๋ผ๋ฉด ๊ฐ์ฒด์ ์ฑ
์ ๋ถ๋ฆฌ ๊ด์ ์์ ๋ง์ง ์๋ค๋ ๊ฒ์ผ๋ก ๊ฒฐ๋ก ์ ๋ด๋ ธ๋ค. (SRP ์๋ฐ)
๊ทธ๋์ ๊ฒฐ๊ณผ์ ์ผ๋ก๋ Custom Exception์ ์์ฑํด์ ์์ธ๊ฐ ๋ฐ์ํ ์ง์ ์์ ๋ฉ์์ง๋ฅผ ๊ด๋ฆฌํ๋ ๋ฐฉํฅ์ผ๋ก ๋ณ๊ฒฝํ์๋ค.
๋๋ฉ์ธ์์ ์ปค์คํ ์์ธ๋ฅผ ๋ฐ์์ํค๋ ๋ฐฉํฅ์ผ๋ก ์งํํ์ จ๊ตฐ์!
๊ทธ๋ผ ๋๋ฉ์ธ์ ์ฐธ์กฐํ ๊ฐ์ฒด ์ ์ฅ์์ ์ปค์คํ ์์ธ๋ฅผ ๊ตฌ๋ถํ ์ ์๋ ๊ธฐ์ค์ด ์๊ฒผ์ต๋๋ค ^_^ ํด๋น ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ ์๋ ์ง์ ์์ ํน์ ํ์ ์ผ๋ก Catch ํ ์ ์์ผ๋๊น์
๊ทธ๋ฌ๋ฉด ํน์ ํ ๋๋ฉ์ธ ์์ธ๋ฅผ Catchํด์ ๋ค๋ฅธ ๋ฉ์์ง๋ก ๋ฐ๊ฟ ์ถ๋ ฅํ ์๋ ์๊ฒ ์ฃ ?
๋ ๋์๊ฐ ๋๋ฉ์ธ ์์ธ๋ฅผ ๊ทธ๋ฃนํ (RuntimeException์ ์์ํ๋ ServiceException์ ๋ง๋ค๊ณ ๊ฐ ๋๋ฉ์ธ ์์ธ๋ ServiceException์ ์์)ํ๋ ์์ผ๋ก "ํน์ ๊ทธ๋ฃน์ ์์ธ๋ A ๋ฉ์์ง๋ก ์ผ๊ด์ฒ๋ฆฌ" ๊ฐ์ ๋ก์ง๋ ๋ง๋ค ์ ์๊ฒ ์ต๋๋ค.
๋ฆฌ๋ทฐ์ด๋ ์ต๊ณ ... ๐
ํ์ง๋ง ์ด๋ฐ ๊ด์ ์์ ์๊ฐํด๋ณด์์ ๋ ๋ชจ๋ ๋๋ฉ์ธ๋ง๋ค ์์ธ ๋ฉ์์ง๋ฅผ ๋ถ๋ฆฌํด์ ๊ด๋ฆฌํด์ผ ํ ๊น? ๋ผ๋ ๋ฌธ์ ๋ ์๊ธด๋ค.
์์ธ ๋ฉ์์ง์ ๋ํ ํด๋์ค๊ฐ 10๊ฐ, 20๊ฐ...๋ก ๋์ด๋๊ฒ ๋๋ค๋ฉด ๊ฒฐ๊ตญ ๊ทธ๊ฑฐ์ ๋ํ ๊ด๋ฆฌ ๋น์ฉ๋ ๋์ด๋๊ธฐ ๋๋ฌธ์ด๋ค.
๊ทธ๋์ ์ฒ์์๋ ๋ฒ์ฉ์ ์ผ๋ก ์ฌ์ฉํ ์ ์๋๋ก ๋ง๋ค์์ผ๋, ๋ฆฌ๋ทฐ์ด๋์ ์คํ๋ ค ์ฌ๋ฌ ๊ฐ๊ฐ ์์ด๋ ์๊ด์๋ค๊ณ ๋ง์ํด ์ฃผ์
จ๋ค.
โจ ๊ทธ๋์ ๋๋ ๋๋ง์ ๊ธฐ์ค์ ์ธ์ ๋ค.
1. ํฐ ๋ฒ์์ ์์ธ ๋ง๋ค๊ธฐ
2. ๋ด๋ถ์ ์ผ๋ก ํด๋น ์์ธ๋ฅผ ์์๋ฐ์ ์ปค์คํ
์์ธ๋ฅผ ๋ง๋ค๊ธฐ
- ์ด๋, ์์ธ ๋ฉ์์ง๋ ์์ธ ๋ฐ์ ์ง์ ์์ ๊ด๋ฆฌํ๋๋ก ๋ง๋ค๊ธฐ
- ์์ธ ๋ฉ์์ง๊ฐ ๋ณ๊ฒฝ๋๋ฉด ํ
์คํธ ์ฝ๋๋ ๋ฐ๋๊ฒ ์ง๋ง, ํ๋ก๋์
์ฝ๋๋ณด๋ค ํ
์คํธ ์ฝ๋๊ฐ ์์ฃผ๊ฐ ๋ ์ ์๋ค.
ํ
์คํธ๊ฐ ์ฌ์์ง๋ ๋ฐฉํฅ๋ณด๋ค๋, ํ๋ก๋์
์ฝ๋๊ฐ ๋ ์ฝ๊ฒ ๋ง๋ค์ด์ง๋๋ก ํ๋ ๊ฒ์ด ์ฐ์ !
๋ฒ์ฉ์ ์ผ ํ์๊ฐ ์๋ค. ์ฝ๋ ์ค๋ณต์ ์ค์ด๋ ๊ฑด ์ข์ง๋ง, ํ์ฅ์ฑ์ ๊ฐ์ฒด๊ฐ ์ฌ๋ฌ ๊ณณ์์ ์ฐ์ธ๋ค๋ ๊ฒ๊ณผ ๋์ผํ ์๋ ์๋ค.
๊ฐ์ฒด๋ ํน์ ์ญํ ๋ง ์ํํ๋ฉด ๋๋ค. ๊ฒฐํฉ๋๊ฐ ๋์์ง๋ ๊ฒ์ ์ข์ง ์๋ค.
๋ฆฌ๋ทฐ์ด๋์ ๋ง์ ์ค์ ๊ฐ์ฅ ์ธ์๊น์ ๋ถ๋ถ์ ๊ฐ์ ธ์๋ค.
์ด๋ฒ ๋ฏธ์
์ ์งํํ๋ฉด์ ๊ฐ์ฒด์งํฅ์ ํ ๋ฐ์ง ๋ค๊ฐ๊ฐ ๋๋์ด๋ค.
๐ฌ ํ๋ก๊ทธ๋จ ์คํ ์ข ๋ฃ์ ๋ก์ง
private void printGameResultWithRetry(final Participants participants, final List<String> ladderResultNames) {
List<Participant> resultParticipants;
do {
resultParticipants = getResultParticipants(participants);
printGameResult(resultParticipants, ladderResultNames);
} while (isProceed(resultParticipants));
}
private List<Participant> getResultParticipants(final Participants participants) {
return inputView.getInputWithRetry(() -> {
String resultParticipantName = inputView.getResultParticipantName();
return getParticipants(participants, resultParticipantName);
});
}
private List<Participant> getParticipants(final Participants participants, final String resultParticipantName) {
if (resultParticipantName.equalsIgnoreCase(EXIT_INPUT_MESSAGE.getMessage())) {
return null;
}
return participants.getResultParticipants(resultParticipantName);
}
private boolean isProceed(final List<Participant> resultParticipants) {
return resultParticipants != null;
}
private void printGameResult(final List<Participant> resultParticipants,
final List<String> ladderResultNames) {
if (resultParticipants == null) {
return;
}
OutputView.print(System.lineSeparator() + RESULT_GAME_GUIDE.getMessage());
outputView.printLadderGameResult(resultParticipants, ladderResultNames);
}
}
์ฝ๋๊ฐ ๊ธธ์ด์ ์์๋ณด๊ธฐ ํ๋ค๊ฒ ์ง๋ง...!
EXIT๋ฅผ ์
๋ ฅํ์ ๋ ํ๋ก๊ทธ๋จ์ด ์ข
๋ฃ๋๋๋ก ๋ง๋ ๋ถ๋ถ์ด๋ค.
๋ค๋ง, ์ข
๋ฃ ์กฐ๊ฑด์ผ๋ก getParticipants()์์ ๋ช
์์ ์ผ๋ก null์ ๋ฐํํ๋๋ก ๋ง๋ ๊ฒ์ธ๋ฐ (์ฌ์ฉ์๊ฐ ์
๋ ฅํ console ๋ฉ์์ง์ String ๊ฐ์ null์ด ๋ค์ด์ฌ ์ ์๊ธฐ ๋๋ฌธ์ Exit๋ฅผ ์
๋ ฅํ์ ๊ฒฝ์ฐ ์ฌ์ฉ์ ๋ชฉ๋ก์ ๋ํด null์ ๋ฐํํ๋๋ก ์ฒ๋ฆฌ) ๋ด๊ฐ ๋ด๋ ์ด ๋ถ๋ถ์ ์ด์ํ๋ค. ใ
ใ
๊ทธ๋์ ์ด์ ๋ํด ๋ฆฌ๋ทฐ์ด๋์ด ๋ค์๊ณผ ๊ฐ์ ํผ๋๋ฐฑ์ ์ฃผ์
จ๋ค.
๋ฆฌ๋ทฐ๋ฅผ ๋ฃ๊ณ ๋จธ๋ฆฌ๊ฐ ๋ตํ๋ค. ๊ฒฐ๊ตญ null์ ๋ฐ๊ฒ ๋ ์ด์ ๋, List ์์ฒด๋ก๋ ํํํ ์ ์๋ ๊ฐ๋
์ด ์กด์ฌํ๊ธฐ ๋๋ฌธ์ด๋ค.
๊ฐ์ฒด์ ์ฑ
์์ ์ด๋์์ ์ค๋๊ฐ?๋ก ์๊ฐํด๋ดค์ ๋, ํ์ํ ๊ธฐ๋ฅ๋ค์ ๋ํด ์ํํ๋ ์ญํ ์ ํ๋ ๊ฒ์ด๊ฒ ๊ตฌ๋...! ์ด๋ ํ ๊ธฐ๋ฅ์ ์ํํ๋ ์ญํ ์ ์ํด ๊ฐ์ฒด๋ฅผ ์์ฑํ ์ ์๊ฒ ๊ตฌ๋! ๋ผ๊ณ ๊นจ๋ฌ์ ์ ์์๋ค.
๊ทธ๋์ ๋ค์ ํผ๋๋ฐฑ์๋ DTO๋ฅผ ํ์ฉํด์ฃผ์๋ค.
public class ResultParticipantsDto {
private final boolean isProceed;
private final List<Participant> participants;
public ResultParticipantsDto(final List<Participant> participants, final boolean isProceed) {
this.participants = participants;
this.isProceed = isProceed;
}
public static ResultParticipantsDto create(final List<Participant> participants, final boolean isProceed) {
return new ResultParticipantsDto(participants, isProceed);
}
public boolean isProceed() {
return isProceed;
}
public List<Participant> getParticipants() {
return List.copyOf(participants);
}
๋ค์๊ณผ ๊ฐ์ด ํ์ฌ ์งํ ์ค์ธ ์ํ์ ๋ํด์๋ ๊ฐ์ ๊ฐ์ง๊ณ ์๊ณ , ์ฐธ๊ฐ์์ ๋ฆฌ์คํธ์ ๋ํด์๋ ๊ฐ์ง ๊ฒฐ๊ณผ DTO๋ฅผ ํ์ฉํ๋ ๊ฒ์ด๋ค.
private void printGameResultWithRetry(final Participants participants, final List<String> ladderResultNames) {
ResultParticipantsDto resultParticipantsDto;
do {
resultParticipantsDto = getResultParticipantsDto(participants);
outputView.printLadderGameResult(resultParticipantsDto, ladderResultNames);
} while (resultParticipantsDto.isProceed());
}
private ResultParticipantsDto getResultParticipantsDto(final Participants participants) {
return inputView.getInputWithRetry(() -> {
String resultParticipantName = inputView.getResultParticipantName();
return makeResultParticipantsDto(participants, resultParticipantName);
});
}
private ResultParticipantsDto makeResultParticipantsDto(final Participants participants, final String resultParticipantName) {
if (resultParticipantName.equalsIgnoreCase(EXIT_INPUT_MESSAGE.getMessage())) {
return ResultParticipantsDto.create(Collections.emptyList(), false);
}
List<Participant> resultParticipants = participants.getResultParticipants(resultParticipantName);
return ResultParticipantsDto.create(resultParticipants, true);
}
}
๋๋ถ์ null์ ๋ฐํํ์ง ์๊ณ , isProceed์ ๋ํ false / true, ๊ทธ๋ฆฌ๊ณ Collections.emptyList() ๋ฅผ ์ฌ์ฉํ๋ฉด์ ๋ ์ฉ์ดํ๊ฒ ์ฒ๋ฆฌํ ์ ์์๋ค. NPE๋ ํผํ์...! ์ด๋์ ์ฝํ๋ฆฐ์ ๋ง์ด ์ ํธํ๋๊ตฌ๋...๋ ๋ฐฐ์ธ ์ ์๋ ๐
์ฌ์ค ์ด๊ฒ ์ธ์๋ ๋๊ฒ ๋ง์ ๊ฒ๋ค์ ๋ฐฐ์ ์ง๋ง...!
PR ์ปค๋ฉํธ์์ ์ถฉ๋ถํ ๋๋ฌ๋ ๊ฒ๋ค์ด๊ธฐ ๋๋ฌธ์ ์ด์ ๋๋ก ์์ฑํด๋๊ฒ ๋ค.
์ฌ๋ค๋ฆฌ ๋ฏธ์
์ ๋ฆฌ๋ทฐ์ด๋์ด ๋๋ฌด๋๋ฌด๋๋ฌด ์ข์์ด์ ๋ ๋ฒจ 1 ๋ฏธ์
์ค ๊ฐ์ฅ ํ๋ณตํ๋ค :D
์ผ๋ฅธ ๋ค๋ฅธ ๋ฏธ์
๋ค๋ ํ๊ณ ๊ธ์ ์์ฑํด์ผ๊ฒ ๋ค ใ
ใ
;;
'์ฐ์ํํ ํฌ์ฝ์ค > ๋ ๋ฒจ 1' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[์ฐํ ์ฝ 5๊ธฐ] ๋ ๋ฒจ 1 ๋ ๋ฒจ ์ธํฐ๋ทฐ ์ ๋ฆฌ ๋ฐ ๊ฐ์ ํ๊ณ (4) | 2023.04.06 |
---|---|
[์ฐํ ์ฝ 5๊ธฐ] ์ฒด์ค ๊ฒ์ ๊ตฌํ ๋ฏธ์ ํ๊ณ (0) | 2023.04.05 |
[์ฐํ ์ฝ 5๊ธฐ] ๋ธ๋์ญ ๊ตฌํ ๋ฏธ์ ํ๊ณ (0) | 2023.04.04 |
[์ฐํ ์ฝ 5๊ธฐ] ์๋์ฐจ ๊ฒฝ์ฃผ ๊ฒ์ ํ๊ณ (0) | 2023.02.22 |
[์ฐํ ์ฝ 5๊ธฐ] 1์ฃผ์ฐจ ํ๊ณ ๋ก - ์ฐ๊ทน, ์๋์ฐจ ๊ฒฝ์ฃผ ๊ฒ์ ๊ตฌํํ๊ธฐ (2) | 2023.02.13 |