DevLog ๐Ÿ˜ถ

[์šฐํ…Œ์ฝ” 5๊ธฐ] ์ž๋™์ฐจ ๊ฒฝ์ฃผ ๊ฒŒ์ž„ ํšŒ๊ณ  ๋ณธ๋ฌธ

์šฐ์•„ํ•œํ…Œํฌ์ฝ”์Šค/๋ ˆ๋ฒจ 1

[์šฐํ…Œ์ฝ” 5๊ธฐ] ์ž๋™์ฐจ ๊ฒฝ์ฃผ ๊ฒŒ์ž„ ํšŒ๊ณ 

dolmeng2 2023. 2. 22. 10:39

์ž๋™์ฐจ ๊ฒฝ์ฃผ ๊ฒŒ์ž„์€ ์ €๋ฒˆ ์ฃผ์— ๋๋‚ฌ์ง€๋งŒ... ์ƒˆ๋กœ์šด ๋ฏธ์…˜์— ์ ์‘ํ•˜๋Š๋ผ ์ด์ œ์„œ์•ผ ํšŒ๊ณ ๋ฅผ ์ž‘์„ฑํ•œ๋‹ค... ๐Ÿฅน

์ค€ํŒ์ด๋ž‘ ์ง„ํ–‰ํ•œ ์ฒซ ํŽ˜์–ดํ”„๋กœ๊ทธ๋ž˜๋ฐ์ด๋‹ค. 

ํ•˜๋‚˜์˜ ๋…ธํŠธ๋ถ์œผ๋กœ ๊ฐ™์ด ์ฝ”๋”ฉํ•˜๋Š” ๊ฑด ์ฒ˜์Œ ํ•ด๋ณด๋Š” ๊ฒฝํ—˜์ด๋ผ ์ƒ‰๋‹ฌ๋ž๋‹ค.

์ง€๊ธˆ ์™€์„œ ๋Š๋ผ๋Š” ๊ฑฐ์ง€๋งŒ, ํ˜ผ์ž ์ฝ”๋”ฉํ•  ๋•Œ๋ณด๋‹ค ์‹œ๊ฐ„์€ ๋” ๊ฑธ๋ ค๋„ ํŽ˜์–ด์—๊ฒŒ ๋ถ€๋„๋Ÿฝ์ง€ ์•Š์€ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ธฐ ์œ„ํ•ด์„œ ๋” ์ข‹์€ ๋ฐฉํ–ฅ์œผ๋กœ ์„ค๊ณ„ํ•˜๊ธฐ ์œ„ํ•ด์„œ ์˜์‹์ ์œผ๋กœ ๋…ธ๋ ฅํ•˜๊ฒŒ ๋˜๋Š” ๊ฒƒ ๊ฐ™๋‹ค.

ํšŒ๊ณ ๋ฅผ ์–ด๋–ป๊ฒŒ ์ž‘์„ฑํ• ๊นŒ ๊ณ ๋ฏผํ–ˆ๋Š”๋ฐ, ์ฝ”๋“œ๋Š” ๋‹จ๊ณ„๋ณ„๋กœ branch๊ฐ€ ๋‚˜๋‰˜์–ด์ ธ ์žˆ๊ณ , ๊ธฐ๋Šฅ ๋ชฉ๋ก๋„ ๋” ์ƒ์„ธํ•˜๊ฒŒ ์ž‘์„ฑ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ฝ”๋“œ์— ๋Œ€ํ•œ ์„ค๋ช…๋ณด๋‹ค๋Š” ์–ด๋–ค ์‹์œผ๋กœ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ–ˆ๋Š”์ง€ ์ ๋Š” ๊ฒŒ ๋” ์ข‹์„ ๊ฒƒ ๊ฐ™์•„์„œ ๊ทธ๋ ‡๊ฒŒ ์ ์–ด๋ณด๋ ค๊ณ  ํ•œ๋‹ค :D

 

โœ”๏ธ ์ž‘์„ฑํ•œ ์ฝ”๋“œ 

 

GitHub - Cl8D/java-racingcar: ์ž๋™์ฐจ ๊ฒฝ์ฃผ ๊ฒŒ์ž„ ๋ฏธ์…˜ ์ €์žฅ์†Œ

์ž๋™์ฐจ ๊ฒฝ์ฃผ ๊ฒŒ์ž„ ๋ฏธ์…˜ ์ €์žฅ์†Œ. Contribute to Cl8D/java-racingcar development by creating an account on GitHub.

github.com

โœ”๏ธ 1์ฐจ PR

 

[1๋‹จ๊ณ„ - ์ž๋™์ฐจ ๊ฒฝ์ฃผ ๊ตฌํ˜„] ์ ธ๋‹ˆ(์ด์ง€์›) ๋ฏธ์…˜ ์ œ์ถœํ•ฉ๋‹ˆ๋‹ค. by Cl8D · Pull Request #455 · woowacourse/java-

์•ˆ๋…•ํ•˜์„ธ์š”! ์šฐํ…Œ์ฝ” 5๊ธฐ ๋ฐฑ์—”๋“œ ํฌ๋ฃจ ์ ธ๋‹ˆ์ž…๋‹ˆ๋‹ค โ›„๏ธ ์ค€ํŒ๊ณผ ํ•จ๊ป˜ ์ฒซ ํŽ˜์–ด ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋„ˆ๋ฌด ์žฌ๋ฐŒ๊ฒŒ ์ง„ํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค! ์ฝ”๋“œ์—์„œ ๋ถ€์กฑํ•œ ์ , ์ˆ˜์ •ํ–ˆ์œผ๋ฉด ์ข‹๊ฒ ๋Š” ์  ์•„๋‚Œ์—†์ด ํ”ผ๋“œ๋ฐฑ ํ•ด์ฃผ์‹œ๋ฉด ๊ฐ์‚ฌ๋“œ

github.com

โœ”๏ธ 2์ฐจ PR 

 

[2๋‹จ๊ณ„ - ์ž๋™์ฐจ ๊ฒฝ์ฃผ ๋ฆฌํŒฉํ„ฐ๋ง] ์ ธ๋‹ˆ(์ด์ง€์›) ๋ฏธ์…˜ ์ œ์ถœํ•ฉ๋‹ˆ๋‹ค. by Cl8D · Pull Request #619 · woowacourse/

์•ˆ๋…•ํ•˜์„ธ์š”, ๋˜๋ง! ๐Ÿ˜Ž ์ง€๋‚œ 1๋‹จ๊ณ„ ๋ฏธ์…˜ ๋•Œ ๊ผผ๊ผผํ•œ ํ”ผ๋“œ๋ฐฑํ•ด ์ฃผ์…”์„œ ์ •๋ง ๊ฐ์‚ฌ๋“œ๋ ค์š”! 1๋‹จ๊ณ„ ๋ฏธ์…˜ ๋•Œ ์„œ๋กœ ์ด์•ผ๊ธฐ ๋‚˜๋ˆด๋˜ ๋ถ€๋ถ„์— ๋Œ€ํ•ด ๋‹ต๊ธ€ ๋‹ฌ์•˜๋Š”๋ฐ, ์งˆ๋ฌธ ์ฃผ์‹  ๋ถ€๋ถ„์— ๋Œ€ํ•ด์„œ ํ•˜์ดํผ๋งํฌ๋ฅผ ๋‹ฌ์•„

github.com


โœ”๏ธ ๊ธฐ๋Šฅ ์š”๊ตฌ์‚ฌํ•ญ

- ์ฃผ์–ด์ง„ ํšŸ์ˆ˜ ๋™์•ˆ n๋Œ€์˜ ์ž๋™์ฐจ๋Š” ์ „์ง„ ๋˜๋Š” ๋ฉˆ์ถœ ์ˆ˜ ์žˆ๋‹ค.
- ๊ฐ ์ž๋™์ฐจ์— ์ด๋ฆ„์„ ๋ถ€์—ฌํ•  ์ˆ˜ ์žˆ๋‹ค. ์ „์ง„ํ•˜๋Š” ์ž๋™์ฐจ๋ฅผ ์ถœ๋ ฅํ•  ๋•Œ ์ž๋™์ฐจ ์ด๋ฆ„์„ ๊ฐ™์ด ์ถœ๋ ฅํ•œ๋‹ค.
- ์ž๋™์ฐจ ์ด๋ฆ„์€ ์‰ผํ‘œ(,)๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๊ตฌ๋ถ„ํ•˜๋ฉฐ ์ด๋ฆ„์€ 5์ž ์ดํ•˜๋งŒ ๊ฐ€๋Šฅํ•˜๋‹ค.
- ์‚ฌ์šฉ์ž๋Š” ๋ช‡ ๋ฒˆ์˜ ์ด๋™์„ ํ•  ๊ฒƒ์ธ์ง€๋ฅผ ์ž…๋ ฅํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค.
- ์ „์ง„ํ•˜๋Š” ์กฐ๊ฑด์€ 0์—์„œ 9 ์‚ฌ์ด์—์„œ random ๊ฐ’์„ ๊ตฌํ•œ ํ›„ random ๊ฐ’์ด 4 ์ด์ƒ์ผ ๊ฒฝ์šฐ ์ „์ง„ํ•˜๊ณ , 3 ์ดํ•˜์˜ ๊ฐ’์ด๋ฉด ๋ฉˆ์ถ˜๋‹ค.
- ์ž๋™์ฐจ ๊ฒฝ์ฃผ ๊ฒŒ์ž„์„ ์™„๋ฃŒํ•œ ํ›„ ๋ˆ„๊ฐ€ ์šฐ์Šนํ–ˆ๋Š”์ง€๋ฅผ ์•Œ๋ ค์ค€๋‹ค. ์šฐ์Šน์ž๋Š” ํ•œ ๋ช… ์ด์ƒ์ผ ์ˆ˜ ์žˆ๋‹ค.


โœ”๏ธ 1์ฐจ ํŽ˜์–ด ํ”„๋กœ๊ทธ๋ž˜๋ฐ

๋‹น์‹œ์—๋Š” TDD๊ฐ€ ๊ทธ๋ƒฅ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋งŒ ์ž‘์„ฑํ•˜๋ฉด ๋˜๋Š” ๊ฑด ์ค„ ์•Œ๊ณ  ๊ธฐ๋Šฅ ๊ตฌํ˜„๋ถ€ํ„ฐ ๋‹ค ํ•˜๊ณ  ๋‚˜์„œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ๋’ค๋Šฆ๊ฒŒ ์ž‘์„ฑํ–ˆ์—ˆ๋‹ค.

๊ทธ๋ž˜์„œ ์ปค๋ฐ‹ ๋‚ด์—ญ์„ ๋ณด๋ฉด ์ด๋ ‡๋‹ค. ๋ˆ„๊ฐ€ ๋ด๋„ ๊ธฐ๋Šฅ ๋จผ์ € ๊ตฌํ˜„ํ•˜๊ณ  ํ…Œ์ŠคํŠธ ๊ตฌํ˜„ํ•œ ์‚ฌ๋žŒ... ๐Ÿฅน

๊ทธ๋ž˜๋„ ๋‹น์‹œ ์ž‘์„ฑํ•œ ์ผ๊ธฐ๋ฅผ ๋ณด๋ฉด ์ตœ๋Œ€ํ•œ ์ด๋Ÿฐ ๋‚ด์šฉ์„ ๊ตฌํ˜„ํ–ˆ๋‹ค.

 

1. ๋„๋ฉ”์ธ์—์„œ getter ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ธฐ

2. DTO๋ฅผ ํ†ตํ•œ ๋ฐ์ดํ„ฐ ์ „๋‹ฌ

3. Stream์„ ํ™œ์šฉํ•˜์—ฌ filter๋ฅผ ํ†ตํ•ด ์กฐ๊ฑด ๊ฒ€์ฆ

4. private ๋ฉ”์„œ๋“œ ํ…Œ์ŠคํŠธ -> ๋ฆฌํ”Œ๋ž™์…˜ ์‚ฌ์šฉํ•˜๊ธฐ (...)

5. ์ž๋™์ฐจ ์ด๋ฆ„์— ๋Œ€ํ•œ equals, hashcode ์˜ค๋ฒ„๋ผ์ด๋”ฉ์„ ํ†ตํ•ด ์ž๋™์ฐจ ๊ฐ์ฒด ๊ด€๋ฆฌํ•˜๊ธฐ

 

์ง€๊ธˆ ์™€์„œ ์ƒ๊ฐํ•ด๋ณด๋ฉด ์ •๋ง ๋ถ€๋„๋Ÿฝ๋‹ค. ๋„๋ฉ”์ธ์—์„œ Getter๋ฅผ ๋ฌด์ž‘์ • ์ง€์–‘ํ•˜๊ณ , DTO ๋ฌด์ž‘์ • ์‚ฌ์šฉํ•˜๊ณ , ๋ฌด์—‡๋ณด๋‹ค ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ๋ฆฌํ”Œ๋ž˜๊ฒฌ๊นŒ์ง€ ์‚ฌ์šฉํ•˜๋ฉด์„œ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฑด ๋‚ญ๋น„์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. (๋‹น์‹œ์—๋Š” ์ด๊ฑฐ ๊ตฌํ˜„ํ•˜๊ณ  ์—„์ฒญ ๋ฟŒ๋“ฏํ–ˆ๋‹ค. ์›๋ž˜ ๋ถ€๋„๋Ÿฌ์šด ๊ฐ์ •์ด ์„ฑ์žฅํ–ˆ๋‹ค๋Š” ์ฆ๊ฑฐ๋ผ๊ณ  ํ–ˆ๋‹ค...ใ…Žใ…Ž)


โœ”๏ธ 1์ฐจ PR 

์ค€ํŒ๊ณผ ๊ฐ™์ด ํ”ผ๋“œ๋ฐฑ์„ ํ•ฉ์ณ์„œ ์„œ๋กœ ์ฝ”๋“œ์— ๋Œ€ํ•œ ๋ฌธ์ œ์ ์„ ์ •๋ฆฌํ•˜๊ธฐ๋กœ ํ–ˆ๋‹ค.

 

๐Ÿ’ฌ ๋ทฐ์˜ ์ถœ๋ ฅ์„ ๋„๋ฉ”์ธ์—์„œ ๊ด€๋ฆฌํ•œ ๊ฒƒ

public class Car {

    private final String name;

    private final StringBuilder drivingMark;

    private Car(final String name) {
        ...
    }

    public static Car of(final String name) {
        return new Car(name);
    }

    public void move() {
        drivingMark.append("-");
    }
    ...
}

๋งŒ์•ฝ ๋ทฐ์— ๋Œ€ํ•œ ์ถœ๋ ฅ ์กฐ๊ฑด์ด ๋ณ€๊ฒฝ๋œ๋‹ค๋ฉด ๋„๋ฉ”์ธ๋„ ํ•จ๊ป˜ ๋ณ€๊ฒฝ๋œ๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ๋‹ค. ๋น„๊ต์  ๋ณ€๊ฒฝ์ด ์žฆ์€ ๋ถ€๋ถ„์ธ ์ถœ๋ ฅ ์กฐ๊ฑด์— ๋Œ€ํ•ด์„œ ์ด๋ ‡๊ฒŒ ๋„๋ฉ”์ธ๊ณผ ์—ฐ๊ด€์„ ์ง€์œผ๋ฉด ์•ˆ ๋œ๋‹ค ๐Ÿฅฒ  (๋„๋ฉ”์ธ๋„ ํ•จ๊ป˜ ๋ณ€ํ•˜๊ฒŒ ๋˜๋‹ˆ๊นŒ) ๊ทธ๋ž˜์„œ ์ถ”ํ›„ ๋ฆฌํŒฉํ† ๋ง ๋•Œ ์ž๋™์ฐจ๋Š” position๋งŒ ๊ฐ€์ง€๊ณ  ์žˆ๋„๋ก ๋งŒ๋“ค๊ณ , ์ถœ๋ ฅ์— ๋Œ€ํ•œ ์ž‘์—…์€ view์—์„œ ์ฒ˜๋ฆฌํ•˜๋„๋ก ๋ณ€๊ฒฝํ•˜์˜€๋‹ค.

 

๋˜ํ•œ, toString()์„ ํ†ตํ•ด์„œ ๋‹น์‹œ์—๋Š” ์ž๋™์ฐจ ์ด๋ฆ„๊ณผ ์ฃผํ–‰๊ฑฐ๋ฆฌ๋ฅผ ์ถœ๋ ฅํ•˜๋ ค๊ณ  ํ–ˆ์œผ๋‚˜ (์‚ฌ์‹ค ํ”„๋ฆฌ์ฝ”์Šค ๋•Œ ๊ทธ๋ ‡๊ฒŒ ํ•ด์™”๋˜ ๊ฒŒ ๋ฒ„๋ฆ‡์ด ๋˜์—ˆ๋‹ค.) ์ด ๋ถ€๋ถ„๋„ ๋ฆฌ๋ทฐ์–ด๋‹˜์ด toString()์˜ ๋ชฉ์ ์„ฑ์— ๋Œ€ํ•ด ์ƒ๊ฐํ•ด ๋ณด๋ผ๊ณ  ํ•˜์…”์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •์˜๋‚ด๋ ธ๋‹ค.

toString()์„ ์žฌ์ •์˜ํ•˜๋Š” ๊ฑด ์ข‹์ง€๋งŒ, ๋ณดํ†ต ํ•„๋“œ์˜ ๋‚ด์šฉ์ด ๋‹ค ๋‚˜์™€์•ผ ํ•˜๋ฉด์„œ, ๋กœ๊น… ์šฉ๋„๋กœ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์šฐ๋ฆฌ์ฒ˜๋Ÿผ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ณด์—ฌ์ง€๋Š” ์šฉ๋„ (= ๋ทฐ์—์„œ ์ฒ˜๋ฆฌํ•  ์ผ)๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฑฐ๋Š” ๋งž๊ฒŒ ์“ฐ์ด์ง€ ์•Š์€ ๊ฒƒ์ด์—ˆ๋‹ค.

 

 

๐Ÿ’ฌ ์—ญํ• ๊ณผ ์ฑ…์ž„์˜ ๋ถ„๋ฆฌ

public class InputUtil {

    private final InputView inputView = new InputView();

    public <T> T getUserInput(Supplier<T> inputReader) {
        try {
            return inputReader.get();
        } catch (IllegalArgumentException | DuplicateException | ConsoleException e) {
            OutputView.printMessage(e.getMessage());
            return getUserInput(inputReader);
        }
    }

    public Cars getCarNames() {
        OutputView.printMessage(GET_CAR_NAMES_MESSAGE.getValue());
        String carNames = inputView.getUserInput();
        return Cars.of(carNames);
    }
    ...
}

1์ฐจ ๋•Œ๋Š” InputUtil์„ ๋ณ„๋„๋กœ ๋‘์–ด์„œ ์‚ฌ์šฉ์ž์—๊ฒŒ ์žฌ์ž…๋ ฅ์„ ๋ฐ›๋„๋ก ํ–ˆ๋Š”๋ฐ, (์‚ฌ์‹ค ์œ ํ‹ธ ํด๋ž˜์Šค๋Š” ์ด๋ ‡๊ฒŒ ์‚ฌ์šฉํ•˜๋Š” ๊ฒŒ ์•„๋‹ˆ๋‹ค. ๋ณดํ†ต ์œ ํ‹ธ ํด๋ž˜์Šค๋Š” static ๋ฉ”์„œ๋“œ๋‚˜ ํ•„๋“œ๋งŒ ๊ด€๋ฆฌํ•˜๋Š” ํด๋ž˜์Šค์ธ๋ฐ ๋‹น์‹œ์—๋Š” ์ž˜ ๋ชจ๋ฅด๊ณ  ์ผ๋‹ค๐Ÿฅน ) getCarNames๋ฅผ ๋ณด๋ฉด, ๋ทฐ์—์„œ ๋„๋ฉ”์ธ์„ ์ƒ์„ฑํ•˜๋Š” ์—ญํ• ๊นŒ์ง€ ํ•˜๊ณ  ์žˆ๋Š” ๊ฒƒ์ด์—ˆ๋‹ค!

 

์šฐ์„  InputUtil์„ ๋งŒ๋“ค์—ˆ๋˜ ์ด์œ ๋ถ€ํ„ฐ ์ƒ๊ฐํ–ˆ๋‹ค. ๋‚˜๋Š” InputView๋ฅผ ์œ„ํ•œ ์ง„์ž…์ ์œผ๋กœ InputUtil์„ ๋‘์—ˆ์—ˆ๋Š”๋ฐ, ์ด๋Š” InputView์™€ OutputView๋ฅผ ์ด๊ณณ ํ•˜๋‚˜์—์„œ ์ฐธ์กฐํ•˜๋„๋ก ํ•˜๊ณ  ์‹ถ์–ด์„œ์˜€๋‹ค.

๊ทผ๋ฐ ๊ธ€๋กœ ์“ฐ๋‹ˆ๊นŒ ๊ธธ์–ด๋ณด์ด์ง€๋งŒ ๊ฒฐ๋ก ์€ ๊ทธ๊ฑฐ์˜€๋‹ค. ์—ญํ• ๊ณผ ์ฑ…์ž„์„ ์ œ๋Œ€๋กœ ๋ถ„๋ฆฌํ•˜์ง€ ๋ชปํ•œ ๊ฒฐ๊ณผ๋กœ ๋‚˜์˜จ ํ•ดํ”„๋‹... InputView์—์„œ ์ถฉ๋ถ„ํžˆ ์ฒ˜๋ฆฌ๊ฐ€ ๊ฐ€๋Šฅํ•œ ๋‚ด์šฉ์ด์—ˆ๊ณ , ๋‹จ์ง€ inputView์—์„œ ์ฝ˜์†”์— ๋Œ€ํ•œ ์ž…๋ ฅ ๋ฉ”์„œ๋“œ๋งŒ ๋‘๊ณ  ์‹ถ์–ด์„œ ๊ทธ๋žฌ๋˜ ๊ฒƒ์ด์—ˆ๋‹ค. 

ํ”ผ๋“œ๋ฐฑ์„ ๋“ฃ๊ณ  ๋ณด๋‹ˆ ์˜คํžˆ๋ ค ์ง€์šฐ๋Š” ๊ฒŒ ๊น”๋”ํ•  ๊ฒƒ ๊ฐ™์•„์„œ ๊ณผ๊ฐํ•˜๊ฒŒ ์ง€์› ๊ณ , view์—์„œ ๋„๋ฉ”์ธ์„ ์ƒ์„ฑํ•˜๋˜ ๋กœ์ง๋„ ๋ณ€๊ฒฝํ•˜์—ฌ ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ์ƒ์„ฑํ•˜๋„๋ก ์ง„ํ–‰ํ•˜์˜€๋‹ค. ์ด ํ”ผ๋“œ๋ฐฑ ๋•๋ถ„์— ๋„๋ฉ”์ธ๊ณผ ๋ทฐ๋ฅผ ๋‚˜๋ˆ ์•ผ ํ•˜๋Š” ํ™•์‹คํ•œ ์ด์œ ๋ฅผ ์ œ๋Œ€๋กœ ์•Œ๊ฒŒ ๋œ ๊ณ„๊ธฐ์˜€๋‹ค. ๐Ÿ‘

 

 

๐Ÿ’ฌ ๋ฌด๋ถ„๋ณ„ํ•œ DTO ์ƒ์„ฑ

์‚ฌ์‹ค ์›น ๊ฐœ๋ฐœ์— ์ต์ˆ™ํ•ด์ ธ์žˆ๋˜ ๋‚˜๋Š”, DTO๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒŒ ๋„ˆ๋ฌด ๋‹น์—ฐํ•˜๊ฒŒ ๋Š๊ปด์กŒ๊ณ  ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์‚ฌ์šฉํ–ˆ๋‹ค. ํ•˜์ง€๋งŒ, ์™œ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š”์ง€๋Š” ํ•œ ๋ฒˆ๋„ ๊ณ ๋ คํ•œ ์  ์—†์ด ์‚ฌ์šฉํ–ˆ๋˜ ๊ฒƒ์ด์—ˆ๋‹ค ๐Ÿฅน ๊ทธ๋ž˜์„œ ์™œ DTO๋ฅผ ์‚ฌ์šฉํ•˜์…จ๋ƒ๋Š” ์งˆ๋ฌธ์— ๋Œ€ํ•ด ์‰ฝ๊ฒŒ ๋‹ต๋ณ€ํ•  ์ˆ˜ ์—†์—ˆ๋‹ค.

ํ˜„์žฌ Car์—์„œ๋Š” ์ฃผํ–‰ ๊ฒฐ๊ณผ์— ๋Œ€ํ•œ ๋“œ๋ผ์ด๋น™ ๋งˆํฌ(-)๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ํ•ด๋‹น ๋งˆํฌ์˜ ๊ธธ์ด๋งŒ ํ•„์š”ํ•ด์„œ DTO๋ฅผ ํ†ตํ•ด ํฌ์žฅํ•˜์—ฌ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ํ•˜์˜€์Šต๋‹ˆ๋‹ค! ๋ฌผ๋ก  ๋‚ด๋ถ€์ ์œผ๋กœ getter๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ .length()๋ฅผ ํ†ตํ•ด ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋Š” ๋ถ€๋ถ„์ด์—ˆ์ง€๋งŒ, getter๋Š” ํ•ด๋‹น ํ•„๋“œ์˜ ๊ฐ’ ์ž์ฒด๋ฅผ ๋ฆฌํ„ดํ•˜๋Š” ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ชฉ์ ์— ๋ถ€ํ•ฉํ•˜์ง€ ์•Š๋‹ค๊ณ  ํŒ๋‹จํ•˜์˜€๊ณ , ๋ณ„๋„์˜ ํด๋ž˜์Šค๋กœ ์„ ์–ธํ•˜๋ฉด ๋„ค์ด๋ฐ์„ ํ†ตํ•ด ํ•ด๋‹น ๊ฐ’์ด ์–ด๋–ค ๊ฒƒ์„ ์˜๋ฏธํ•˜๋Š”์ง€ ๋” ์ž˜ ๋‚˜ํƒ€๋‚ผ ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค.

๋‹ค๋งŒ ๋ฆฌํŒฉํ† ๋ง ๊ณผ์ •์—์„œ ํ•ด๋‹น ํ•„๋“œ ๋Œ€์‹ ์— position ๊ฐ’์„ ๊ฐ€์งˆ ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ์›์‹œ๊ฐ’์„ ํฌ์žฅํ•˜๊ธฐ ์œ„ํ•ด์„œ ‘dto’๋ผ๋Š” ๋„ค์ด๋ฐ ๋Œ€์‹ ์— ํ•ด๋‹น ๊ฐ’์„ ํฌ์žฅํ•˜๋Š” ‘CarPosition’ ๋“ฑ์˜ ํด๋ž˜์Šค๋กœ ๋‹ค์‹œ ๋ฆฌํŒฉํ† ๋ง ํ•˜๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค. 

์ถ”๊ฐ€์ ์œผ๋กœ, ์›์‹œ๊ฐ’ ํฌ์žฅ์„ ์œ„ํ•ด์„œ ์ฐจ ์ด๋ฆ„ ์—ญ์‹œ ๋ณ„๋„๋กœ ๋ถ„๋ฆฌํ•˜์—ฌ ํฌ์žฅํ•ด์„œ validation์„ ํ•ด๋‹น ํฌ์žฅ ํด๋ž˜์Šค์—์„œ ์ง„ํ–‰ํ•˜๋„๋ก ํ•ด์„œ ๋„๋ฉ”์ธ์— ๋Œ€ํ•œ ์—ญํ• ์„ ์ค„์ด๋Š” ๋ฐฉํ–ฅ์œผ๋กœ ์„ค๊ณ„ํ•ด๋ณด๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค! (์ถ”ํ›„ ํ•„๋“œ๊ฐ€ ์ถ”๊ฐ€๋˜๊ณ , ์ œ์•ฝ ์‚ฌํ•ญ์ด ์ถ”๊ฐ€๋˜๋ฉด Car ๋„๋ฉ”์ธ ํ•˜๋‚˜์—์„œ ๋„ˆ๋ฌด ๋งŽ์€ ์—ญํ• ์„ ํ•  ๊ฒƒ ๊ฐ™๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค :D)

๋‹น์‹œ์—๋Š” ์ด๋ ‡๊ฒŒ ๋‹ต๋ณ€ํ–ˆ์ง€๋งŒ, ์‚ฌ์‹ค ๋„๋ฉ”์ธ์—์„œ DTO๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์žˆ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋„๋ฉ”์ธ์˜ ํ•„๋“œ๋ฅผ getter๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ด์œ ๋กœ ์‚ฌ์šฉํ•˜์˜€๋‹ค. ํ•˜์ง€๋งŒ! ๋„๋ฉ”์ธ์—์„œ DTO๋ฅผ ์ฐธ์กฐํ•˜๋Š” ๊ฒƒ๋„ ์ข‹์ง€ ์•Š๋‹ค๋Š” ์‚ฌ์‹ค์„... 1์ฐจ ๋ฆฌํŒฉํ† ๋ง ์ดํ›„์— ์•Œ๊ฒŒ ๋˜์—ˆ๋‹ค. ์ด๊ฑฐ๋Š” ๋‹ค์‹œ ์–ธ๊ธ‰ํ•  ์˜ˆ์ •! ์•„๋ฌดํŠผ, '์›์‹œ๊ฐ’ ํฌ์žฅ'์ด๋ผ๋Š” ๋ช…๋ชฉํ•˜์— ์ด๋•Œ๊นŒ์ง€๋Š” '์™œ DTO๋ฅผ ์“ฐ๋ฉด ์•ˆ ๋ผ...?' ์ด๋Ÿฌ๊ณ  ์žˆ์—ˆ๋‹ค. ใ…Žใ…Ž

 

 

๐Ÿ’ฌ ์ปจํŠธ๋กค๋Ÿฌ์˜ ์ธํ„ฐํŽ˜์ด์Šค

๋‹น์‹œ ์ปจํŠธ๋กค๋Ÿฌ์— ๋Œ€ํ•œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ–ˆ์—ˆ๋Š”๋ฐ, ์‚ฌ์‹ค ์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ ํ•˜๋‚˜์—ฌ์„œ ๊ต‰์žฅํžˆ ๋ฌด์˜๋ฏธํ–ˆ๋‹ค. ใ…Žใ…Ž ๊ทธ๋ž˜์„œ ๋‹ค์Œ ๋ฆฌํŒฉํ„ฐ๋ง ๋•Œ ๊ณผ๊ฐํ•˜๊ฒŒ ์‚ญ์ œํ•˜์˜€๋‹ค. ์‚ญ์ œํ•˜๋Š” ๊ฒธ ์ธํ„ฐํŽ˜์ด์Šค์— ๋Œ€ํ•ด์„œ ๊ณต๋ถ€๋ฅผ ํ–ˆ์—ˆ๋Š”๋ฐ, ๊ทธ ๋‚ด์šฉ์„ ๋ธ”๋กœ๊ทธ์— ์ •๋ฆฌํ•˜๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™์•„์„œ ์—ฌ๊ธฐ์— ์ ์–ด๋‘”๋‹ค.

 

 

๐Ÿ’ฌ Enum ํ™œ์šฉ, ํ•˜์ง€๋งŒ ์–ด๋””๊นŒ์ง€...?

๊ธฐ์กด์—๋Š” 'DomainConstant'์ด๋ผ๋Š” enum ํ†ตํ•ด์„œ ๋„๋ฉ”์ธ์˜ ์ œ์•ฝ์‚ฌํ•ญ์„ ๋ชจ๋‘ ์—ฌ๊ธฐ์„œ ๊ด€๋ฆฌํ–ˆ๋‹ค. ํ•˜์ง€๋งŒ, ๋„๋ฉ”์ธ์ด ์ปค์ง„๋‹ค๋ฉด...? ๊ทธ๋ ‡๋‹ค๋ฉด ๊ด€๋ฆฌํ•ด์•ผ ํ•˜๋Š” ํ•„๋“œ๊ฐ€ ๋งค์šฐ ๋งŽ์•„์ง€๊ฒŒ ๋œ๋‹ค. ๊ทธ๋ž˜์„œ ๋‹ค์Œ ๋ฆฌํŒฉํ„ฐ๋ง ๋•Œ๋Š” enum ๊ตฌ์กฐ๋ฅผ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์–ด์„œ, ๋„๋ฉ”์ธ๋ณ„๋กœ constant enum์„ ๋ถ„๋ฆฌํ•˜์˜€๋‹ค. (ํ•˜์ง€๋งŒ ์ด ๊ตฌ์กฐ๋„ ์ง€๊ธˆ ์™€์„œ ๋ณด๋ฉด ์•„์‰ฝ๋‹ค.)

 

๋‹น์‹œ, ์™œ enum์œผ๋กœ ์ƒ์ˆ˜๋ฅผ ๊ด€๋ฆฌํ–ˆ๋Š”์ง€์— ๋Œ€ํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ƒ๊ฐํ–ˆ์—ˆ๋‹ค.

์ €๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์ƒ์ˆ˜๋ฅผ enum์œผ๋กœ ๊ด€๋ฆฌํ•˜๋Š” ํŽธ์ธ๋ฐ, enum์œผ๋กœ ๊ด€๋ฆฌํ•˜๋ฉด์„œ ์ข‹์•˜๋˜ ์ ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ง์”€๋“œ๋ฆด ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™์•„์š”!

1. ์ž…์ถœ๋ ฅ ๋ฉ”์‹œ์ง€์˜ ๊ฒฝ์šฐ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ณด์—ฌ์ง€๋Š” ๋ฉ”์‹œ์ง€์ธ ๋งŒํผ ๋ณ€ํ™”๊ฐ€ ์ž์ฃผ ์ผ์–ด๋‚  ์ˆ˜ ์žˆ๋Š” ๋ถ€๋ถ„์ด๋ผ๊ณ  ์ƒ๊ฐ์ด ๋“ค์–ด์š”! ์ด๋•Œ, ํ•ด๋‹น ๋ฉ”์‹œ์ง€๋ฅผ ๋‹ค์–‘ํ•œ ๊ณณ์—์„œ ์ฐธ์กฐํ•˜๋Š” ๊ฒฝ์šฐ ๋ชจ๋“  ๊ณณ์˜ ์ฝ”๋“œ๋ฅผ ๋ฐ”๊ฟ”์ค˜์•ผ ํ•˜๋Š”๋ฐ enum์œผ๋กœ ๊ด€๋ฆฌํ•ด์ฃผ๋ฉด ํ•œ ๊ณณ์—์„œ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด์„œ ๊ด€๋ฆฌ ์ฐจ์›์—์„œ ์šฉ์ดํ•˜๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ค์–ด์š”.

2. ๋„๋ฉ”์ธ ์ œ์•ฝ ์‚ฌํ•ญ์˜ ๊ฒฝ์šฐ, ์ด๋ฒˆ ๊ณผ์ œ์—์„œ๋Š” ๋Œ€๋ถ€๋ถ„ ์ˆซ์ž๊ฐ’์„ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”๋ฐ (ํ”ํžˆ ‘๋งค์ง ๋„˜๋ฒ„’๋ผ๊ณ  ํ•˜์ฃ !) ํ•ด๋‹น ์ˆซ์ž๊ฐ’์— ๋Œ€ํ•ด์„œ ๊ทธ๋Œ€๋กœ ์ฝ”๋“œ์— ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด ์ฝ”๋“œ๋ฅผ ์ฝ๋Š” ์ž…์žฅ์—์„œ ํ•ด๋‹น ๋„˜๋ฒ„๊ฐ€ ๋ฌด์Šจ ์˜๋ฏธ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”์ง€ ํ•œ ๋ˆˆ์— ์•Œ์•„๋ณด๊ธฐ๊ฐ€ ํž˜๋“ค ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ–ˆ์–ด์š”. ๊ทธ๋ž˜์„œ enum์„ ํ†ตํ•ด ํ•ด๋‹น ์ˆซ์ž์— ๋Œ€ํ•ด์„œ ๋ณ„๋„์˜ ๋ช…์นญ์œผ๋กœ ๊ด€๋ฆฌํ•˜๊ณ , ๋˜ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋ณ€๊ฒฝ์ด ์šฉ์ดํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ ๊ณณ์—์„œ ๊ด€๋ฆฌํ•˜๋ ค๊ณ  ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ ๊ฐ™์•„์š”!

๋‹ค๋งŒ, ํ˜„์žฌ๋Š” ๋„๋ฉ”์ธ ์ œ์•ฝ์‚ฌํ•ญ ์ž์ฒด๋ฅผ ํ•˜๋‚˜์˜ ‘DomainConstant’์—์„œ ๊ด€๋ฆฌํ•˜๋‹ค ๋ณด๋‹ˆ๊นŒ, ์ถ”ํ›„ ํ™•์žฅ์„ฑ์„ ๊ณ ๋ คํ•ด๋ดค์„ ๋•Œ ๋„๋ฉ”์ธ์˜ ํฌ๊ธฐ๊ฐ€ ์ปค์ง€๊ฒŒ ๋œ๋‹ค๋ฉด ๋‚ด๋ถ€์— ๋“ค์–ด๊ฐ€์•ผ ํ•˜๋Š” ๊ฐ’์ด ๋งŽ์•„์ ธ์„œ ๋ณต์žก๋„๊ฐ€ ์ฆ๊ฐ€ํ•  ๊ฒƒ ๊ฐ™์•„์š”. ๊ทธ๋ž˜์„œ ์ด๋ฒˆ ๋ฆฌํŒฉํ† ๋ง ๋•Œ ์ œ์•ฝ์‚ฌํ•ญ๋“ค์€ ๊ฐ ๋„๋ฉ”์ธ์— ๋งž๊ฒŒ ํ•œ ๋ฒˆ ๋” ๋ถ„๋ฆฌ ์ž‘์—…์„ ์ง„ํ–‰ํ•ด๋ณด๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค!

๋˜ํ•œ, ๋„๋ฉ”์ธ ๋‚ด์—์„œ ์ƒ์ˆ˜๋ฅผ static final๋กœ ๊ด€๋ฆฌํ•œ๋‹ค๋ฉด ๋‚ด๋ถ€์ ์œผ๋กœ ์กฐ๊ธˆ ๋” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ์ž…์žฅ์—์„œ๋Š” ๋œ ๊ท€์ฐฎ์„(?) ์ˆ˜๋„ ์žˆ์„ ๊ฒƒ ๊ฐ™๊ณ , ๋‹จ์ˆœํžˆ ์ƒ์ˆ˜๊ฐ€ ์•„๋‹ˆ๋ผ enum ์—ญ์‹œ ๋ณ„๋„์˜ ํƒ€์ž…(์ด๋ผ๊ณ  ํ‘œํ˜„ํ•ด๋„ ๋ ์ง€ ๋ชจ๋ฅด๊ฒ ์ง€๋งŒ)์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๋” ์žก์•„๋จน์„ ๊ฒƒ ๊ฐ™์•„์š”…!

ํ•˜์ง€๋งŒ, ์ง€๊ธˆ ์™€์„œ ์ƒ๊ฐํ•ด๋ณด๋ฉด static final๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒŒ ๋” ์ข‹์„ ๊ฒƒ ๊ฐ™๋‹ค. ใ…Žใ…Ž

 

 

๐Ÿ’ฌ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ

@ParameterizedTest
@ValueSource(ints = {4, 9})
@DisplayName("๋žœ๋ค๊ฐ’์ด 4 ์ด์ƒ์ด๋ฉด ์ž๋™์ฐจ๊ฐ€ ์ „์ง„ํ•œ๋‹ค.")
void givenFourMoreNumber_thenCarMove(int randomNumber) throws Exception {
        // given
        Cars cars = TestProvider.createTestCars();
        Car car = TestProvider.createTestCar("pobi");

        // when
        Method method = cars.getClass().getDeclaredMethod("checkNumberAndMove", Car.class, int.class);
        method.setAccessible(true);
        method.invoke(cars, car, randomNumber);

        // then
        assertThat(car)
        .isEqualTo(TestProvider.createTestMoveCar(car));
}

์•„๋งˆ ๋งŽ์ด๋“ค ๊ณ ๋ฏผ์„ ํ–ˆ๋˜ ๋ถ€๋ถ„์ผ ๊ฒƒ์ด๋‹ค. ํ…Œ์ŠคํŠธํ•˜๊ธฐ ์–ด๋ ค์šด ๋ถ€๋ถ„ (=๋žœ๋ค์œผ๋กœ ๊ฐ’์„ ์ƒ์„ฑํ•˜๋Š” ๋ถ€๋ถ„)์— ๋Œ€ํ•ด์„œ ์–ด๋–ค ์‹์œผ๋กœ ํ…Œ์ŠคํŠธ๋ฅผ ํ•  ๊ฒƒ์ธ์ง€ ๋ถ„๋ฆฌ๋ฅผ ํ•ด์•ผ ํ•˜๋Š” ์ƒํ™ฉ์ด๋‹ค. ๊ธฐ์กด์—๋Š” ํ…Œ์ŠคํŠธ ํ•˜๊ธฐ ์–ด๋ ต๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ๋ƒฅ ๋ฆฌํ”Œ๋ž™์…˜์œผ๋กœ ์•„์˜ˆ ๊ฐ’์„ ๋„ฃ์–ด์คฌ๋‹ค. ํ•˜์ง€๋งŒ, ์ด๋Ÿฐ ํ…Œ์ŠคํŠธ ๋ฐฉ์‹์€ ์ง€๋‚˜์น˜๊ฒŒ ๋ณต์žกํ•˜๋‹ค๋Š” ์ƒ๊ฐ์ด ์•„๋ฌด๋ž˜๋„ ๊ฐœ๋ฐœ์ž ์ž…์žฅ์—์„œ ๋“ค ์ˆ˜๋ฐ–์— ์—†๊ณ , ๋ฌด์—‡๋ณด๋‹ค '์ž๋™์ฐจ์˜ ์›€์ง์ž„'์„ ํ…Œ์ŠคํŠธํ•˜๊ธฐ ์œ„ํ•ด์„œ, Cars๊นŒ์ง€ ์ƒ์„ฑํ•˜๋Š” ๊ฑด ์—ญํ• ๊ณผ ์ฑ…์ž„์˜ ๋ถ„๋ฆฌ๊ฐ€ ์ œ๋Œ€๋กœ ์ด๋ฃจ์–ด์ง€์ง€ ์•Š์€ ๊ฒƒ์ด๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

๊ทธ๋ž˜์„œ ๋ฆฌํŒฉํ„ฐ๋ง ๋•Œ ๊ฐ€์žฅ ์‹ ๊ฒฝ์“ฐ๋ฉด์„œ ์ˆ˜์ •ํ•œ ๋ถ€๋ถ„์ด๋‹ค. ํ…Œ์ŠคํŠธํ•˜๊ธฐ ์–ด๋ ค์šด ๋ถ€๋ถ„์€ ์™ธ๋ถ€๋กœ ๋นผ๊ธฐ ์œ„ํ•ด ์ธํ„ฐํŽ˜์ด์Šค์— ๋Œ€ํ•œ Mock ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ์ง„ํ–‰ํ•˜์˜€๋‹ค.


โœ”๏ธ 1์ฐจ ๋ฆฌํŒฉํ„ฐ๋ง

1์ฐจ ๋ฆฌํŒฉํ„ฐ๋ง ๋•Œ๋Š” ๊ฑฐ์˜ ๊ฐˆ์•„์—Ž๋“ฏ์ด ์—„์ฒญ ๋งŽ์ด ์ˆ˜์ •ํ–ˆ๋‹ค. ํฌ๊ฒŒ ๋ฝ‘์•„๋ณด์ž๋ฉด, ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ•ญ๋ชฉ์„ ์ˆ˜์ •ํ–ˆ๋‹ค.

- private method์˜ ํ…Œ์ŠคํŠธ๋Š” ์ตœ๋Œ€ํ•œ public์„ ํ†ตํ•ด ์ง„ํ–‰ํ•˜๋„๋ก ๋งŒ๋“ค๊ธฐ
- ๊ฐ ๊ฐ์ฒด์— ๋Œ€ํ•œ ์—ญํ• ์„ ํ™•์‹คํ•˜๊ฒŒ ํ•˜๊ธฐ (ex. ๋ทฐ์—์„œ Cars, Race ๊ฐ™์€ ๋„๋ฉ”์ธ์„ ์ƒ์„ฑํ•˜์ง€ ์•Š๋„๋ก ๋งŒ๋“ค๊ธฐ)
- Wrapper ํด๋ž˜์Šค ํ™œ์šฉํ•˜๊ธฐ (๊ฐ ํ•„๋“œ์— ๋Œ€ํ•œ ๊ฒ€์ฆ๋„ wrapper์—์„œ ์ง„ํ–‰ํ•˜๊ธฐ)
- ์ •์  ํŒฉํ„ฐ๋ฆฌ ๋ฉ”์„œ๋“œ ์ด์šฉํ•˜๊ธฐ
- ํ™”๋ฉด ์ถœ๋ ฅ์€ view์—์„œ ์ง„ํ–‰ํ•˜๋„๋ก ์ง„ํ–‰ํ•˜๊ธฐ
- ๋ฉ”์„œ๋“œ์˜ ์ˆœ์„œ ๋ณ€๊ฒฝํ•˜๊ธฐ 

์šฐ์„  ๊ฐ€์žฅ ๊ฐ€๋ฒผ์šด ๋ฉ”์„œ๋“œ์˜ ์ˆœ์„œ์˜ ๊ฒฝ์šฐ, ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ˆœ์„œ๋ฅผ ์ง€ํ‚ค๋ ค๊ณ  ํ–ˆ๋‹ค.

ํด๋ž˜์Šค > ์ •์  ๋ณ€์ˆ˜ (public-protected-private) > ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜ > ์ƒ์„ฑ์ž > ์ •์  ๋ฉ”์„œ๋“œ > ๋ฉ”์„œ๋“œ > ์Šคํƒ ๋‹ค๋“œ ๋ฉ”์„œ๋“œ (toString, equals, hashcode...) > getter / setter ๋ฉ”์„œ๋“œ.

 

์ด๋•Œ, public์ด๋ž‘ private ๋ฉ”์„œ๋“œ ์‚ฌ์ด์˜ ์ˆœ์„œ๋ฅผ ๊ณ ๋ฏผํ–ˆ์—ˆ๋Š”๋ฐ public์„ ๋จผ์ € ์„ ์–ธํ•˜๋Š” ๋ฐฉํ–ฅ์œผ๋กœ ์ง„ํ–‰ํ–ˆ๋‹ค. private๋ฅผ public ์‚ฌ์ด์— ์„ ์–ธํ•˜๋Š” ๊ฒƒ์„ ์„ ํ˜ธํ•˜๋Š” ๋ถ„๋“ค๋„ ๊ณ„์‹œ๊ฒ ์ง€๋งŒ, public์„ ๋จผ์ € ๋‘ฌ์•ผ ํ•ด๋‹น ๊ฐ์ฒด๊ฐ€ ํ•˜๋Š” ์ผ์„ ๋ช…ํ™•ํ•˜๊ฒŒ ๋ณผ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— (=public์œผ๋กœ ์„ ์–ธ๋œ ๋ฉ”์„œ๋“œ๋งŒ ๋ฐ”๋กœ ํ™•์ธํ•˜๋ฉด ๋˜๋‹ˆ๊นŒ) ๋‚˜๋Š” public์„ ๋จผ์ € ์ž‘์„ฑํ•˜๋Š” ๋ฐฉํ–ฅ์œผ๋กœ ์ง„ํ–‰ํ–ˆ๋‹ค.

 

 

๐Ÿ’ฌ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‰ฝ๊ฒŒ ๋งŒ๋“ค๊ธฐ

public class Cars {

    private final List<Car> cars;

    private final NumberGenerator numberGenerator;

    private Cars(final String carNames, final NumberGenerator numberGenerator) {
        this.cars = createCars(carNames);
        this.numberGenerator = numberGenerator;
        validateDuplicateCarName();
    }
}

ํ…Œ์ŠคํŠธํ•˜๊ธฐ ์–ด๋ ค์šด ๋ถ€๋ถ„์„ ๋‚˜๋ˆ„๊ธฐ ์œ„ํ•ด์„œ, ๊ธฐ์กด์—๋Š” NumberGenerator๋ฅผ ํ•„๋“œ์—์„œ ๋ฐ”๋กœ ์ฃผ์ž…ํ–ˆ์—ˆ์ง€๋งŒ, ์˜์กด ๊ด€๊ณ„๋ฅผ ์ฃผ์ž…ํ•˜๋Š” ํ˜•์‹์œผ๋กœ ๋ณ€๊ฒฝํ•˜์˜€๋‹ค. (์ธํ„ฐํŽ˜์ด์Šค ์ฃผ์ž…) ์ด ๋•๋ถ„์— ์‹ค์ œ ํ”„๋กœ๊ทธ๋žจ์—์„œ๋Š” RaceNumberGenerator๋ฅผ ํ†ตํ•ด ๋žœ๋ค๊ฐ’์„ ๊ฐ€์ ธ์˜ค๋„๋ก ํ•˜๊ณ , ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์—์„œ๋Š” MockNumberGenerator๋ฅผ ์ฃผ์ž…๋ฐ›์•„์„œ ์›ํ•˜๋Š” ๊ฐ’๋งŒ ๊ณ„์†ํ•ด์„œ ๋ฆฌํ„ด๋ฐ›์„ ์ˆ˜ ์žˆ๋„๋ก ์ง„ํ–‰ํ•˜์˜€๋‹ค.

public class MockNumberGenerator implements NumberGenerator {

    private int randomNumber = 0;

    private final boolean isIncrease;

    public MockNumberGenerator(final boolean isIncrease) {
        this.isIncrease = isIncrease;
    }

    @Override
    public int generate() {
        if (isIncrease) {
            return randomNumber = randomNumber * 2 + 1;
        }
        return randomNumber;
    }
}
    @Test
@DisplayName("์šฐ์Šนํ•œ ์ž๋™์ฐจ๋ฅผ ๋ฝ‘๋Š”๋‹ค.")
    void givenCarInfo_thenPickWinner() {
            // given
            MockNumberGenerator numberGenerator = TestProvider.createMockNumberGenerator(true);
            Cars testCars = TestProvider.createTestCars(testCarNames, numberGenerator);

            // when
            testCars.race();
            List<String> winners = testCars.pickWinners();

            // then
            assertThat(winners.size())
            .isEqualTo(1);

            assertThat(winners)
            .isEqualTo(List.of("honux"));
            }

๋•๋ถ„์— ์šฐ์Šนํ•œ ์ž๋™์ฐจ๋ฅผ ๋ฝ‘๋Š” ๋กœ์ง์—์„œ 1, 3, 5... ์ด๋Ÿฐ ์‹์œผ๋กœ ๊ฐ’์„ ๋ฐ˜ํ™˜๋ฐ›๋„๋ก ํ•˜์—ฌ ์ž๋™์ฐจ 3๊ฐœ๊ฐ€ ๋“ค์–ด์™”์„ ๋•Œ ๋งˆ์ง€๋ง‰ ์ž๋™์ฐจ๋งŒ ์ฃผํ–‰์„ ํ•˜๊ฒŒ ๋˜์–ด์„œ (4 ์ด์ƒ์ด ์ฃผํ–‰ ์กฐ๊ฑด)  ์šฐ์Šนํ•œ ์ž๋™์ฐจ๋ฅผ ๋ฝ‘๊ธฐ๊ฐ€ ์‰ฌ์›Œ์กŒ๋‹ค.

// Car.java
public void move(final int power) {
        if (power >= CAR_FORWARD_NUMBER.getValue()) {
        position.addPosition();
        }
}

๋˜ํ•œ, ๊ธฐ์กด์—๋Š” ์ž๋™์ฐจ๋ฅผ ์ด๋™์‹œํ‚ค๋Š” ๋กœ์ง์„ ์™ธ๋ถ€์—์„œ ํŒ๋‹จํ•ด์„œ, ์ž๋™์ฐจ์—์„œ๋Š” move()๋งŒ ์ง„ํ–‰ํ•˜๋„๋ก ๋งŒ๋“ค์—ˆ์—ˆ๋Š”๋ฐ, ์ž๋™์ฐจ์—๊ฒŒ ๋žœ๋ค๊ฐ’ (=power)์„ ์ฃผ๊ณ  ์ง์ ‘ ์›€์ง์ž„์„ ํŒ๋‹จํ•˜๋„๋ก ํ•ด์„œ, ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ํ†ตํ•ด ์ž๋™์ฐจ์—๊ฒŒ ๋žœ๋ค๊ฐ’์„ ์ฃผ์ž…์‹œํ‚ฌ ์ˆ˜ ์žˆ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ž๋™์ฐจ์— ๋Œ€ํ•œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์—ญ์‹œ ์‰ฝ๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

 

 

๐Ÿ’ฌ Wrapper ํด๋ž˜์Šค ํ™œ์šฉํ•˜๊ธฐ

Wrapper ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด์„œ, ๋„๋ฉ”์ธ์˜ ๋ชจ๋“  ํ•„๋“œ๋งˆ๋‹ค Wrapper๊ฐ€ ์žˆ์–ด์•ผ ํ•˜๋Š”์ง€์— ๋Œ€ํ•œ ์˜๋ฌธ์ด ์žˆ์—ˆ๋‹ค. ์ง€๊ธˆ์€ ๋ฏธ์…˜์ด๊ธฐ ๋•Œ๋ฌธ์— ์ด์™€ ๊ฐ™์ด ๋‹ค ๊ฐ์‹ธ๋Š” ์‹์œผ๋กœ ์ง„ํ–‰ํ–ˆ์ง€๋งŒ, ์ถ”ํ›„์—๋Š” ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์ด ์—†๋Š” ๊ฒฝ์šฐ์—๋Š” ๊ฐ์‹ธ์ง€ ์•Š๊ณ , ๊ฒ€์ฆ ๋กœ์ง ๊ฐ™์€, ๋ณ„๋„์˜ ๋กœ์ง์ด ํ•„์š”ํ•˜๋‹ค๋ฉด ๊ฐ์‹ธ์„œ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒŒ ์ข‹๋‹ค๊ณ  ๋Š๊ผˆ๋‹ค. 

 

 

๐Ÿ’ฌ ์ •์  ํŒฉํ„ฐ๋ฆฌ ๋ฉ”์„œ๋“œ ์ƒ์„ฑํ•˜๊ธฐ

private Car(final String name) {
        this.name = CarName.of(name);
        this.position = CarPosition.of();
        }

์ •์  ํŒฉํ„ฐ๋ฆฌ ๋ฉ”์„œ๋“œ์˜ ๋„ค์ด๋ฐ์— ๋Œ€ํ•ด์„œ ๊ณ ๋ฏผํ•˜๊ฒŒ ๋œ ๊ณ„๊ธฐ์˜€๋‹ค. ์ง€๊ธˆ๊นŒ์ง€ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๋ฉด์„œ ์ด ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ์ฐธ๊ณ ํ•ด์„œ ์ง„ํ–‰ํ–ˆ์—ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๋Œ€๋ถ€๋ถ„ of๋กœ ์ง„ํ–‰ํ–ˆ์—ˆ๋Š”๋ฐ, ์ด๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋„˜์–ด์˜จ ๊ฐ’๋“ค์— ๋Œ€ํ•ด ๊ฒ€์ฆํ•˜์—ฌ ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•  ๋•Œ - ํ˜น์€ ์ง‘๊ณ„ ๋ฉ”์„œ๋“œ์—์„œ ์ฃผ๋กœ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ํ•œ๋‹ค. (ex. List.of) ๊ทธ๋ž˜์„œ create๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ƒˆ๋กœ์šด ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์„ ๋‚˜ํƒ€๋‚ด๋„๋ก ๋ณ€๊ฒฝํ•˜์˜€๋‹ค. ๐Ÿ˜Ž

 

 

๐Ÿ’ฌ ๋„๋ฉ”์ธ์—์„œ DTO๋ฅผ ์ƒ์„ฑํ•˜๊ฒŒ ๋œ๋‹ค๋ฉด...? 

 public List<CarRaceDto> initStatus() {
        return cars.stream()
        .map(Car::getCarRaceResult)
        .collect(Collectors.toList());
}

์œ„์˜ ์ฝ”๋“œ๋Š” Cars์—์„œ ์ดˆ๊ธฐ ์ž๋™์ฐจ์˜ ์ƒํƒœ๋ฅผ ์ถœ๋ ฅํ•ด์ฃผ๋Š” ์ฝ”๋“œ์ด๋‹ค. ๊ทธ๋Ÿฌ๋‚˜, ๋„๋ฉ”์ธ ๋‚ด๋ถ€์—์„œ DTO๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์žˆ๋‹ค๋Š” ์ ์ด๋‹ค.

๋„๋ฉ”์ธ ๋‚ด๋ถ€์—์„œ Dto๋ฅผ ์ƒ์„ฑํ•˜๊ฒŒ ๋œ๋‹ค๋ฉด, Dto์˜ ์ƒ์„ฑ์ž๊ฐ€ ๋ณ€ํ•˜๊ฒŒ ๋˜์—ˆ์„ ๋•Œ ๋„๋ฉ”์ธ ์ฝ”๋“œ ์—ญ์‹œ ํ•จ๊ป˜ ๋ณ€๊ฒฝ๋œ๋‹ค๋Š” ๋‹จ์ ์ด ์กด์žฌํ•ด์š”. Dto์˜ ๊ฒฝ์šฐ ๋„๋ฉ”์ธ์— ๋น„ํ•ด ๋ณ€๊ฒฝ์ด ์žฆ์€ ๋ถ€๋ถ„์ด๊ธฐ ๋•Œ๋ฌธ์—, ๋„๋ฉ”์ธ ๋กœ์ง ์—ญ์‹œ ํ•จ๊ป˜ ๋ณ€๊ฒฝ๋œ๋‹ค๋Š” ์ ์ด ์ข‹์ง€ ์•Š๋‹ค๊ณ  ์ƒ๊ฐ์ด ๋“ค์–ด์š”. ๋˜ํ•œ, DTO๋Š” ์ด๋ฆ„ ๊ทธ๋Œ€๋กœ Data Transfer Object๋กœ์„œ, ๊ณ„์ธต ๊ฐ„์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•ด์ฃผ๋Š” ์—ญํ• ์„ ํ•˜๋Š” ๊ฐ์ฒด์ธ๋ฐ ๋„๋ฉ”์ธ์ด DTO๋ฅผ ์˜์กดํ•˜๊ฒŒ ๋˜๋Š” ๊ฑด ์ด์ƒํ•˜๋‹ค๊ณ  ์ƒ๊ฐ์ด ๋“ค์–ด์š”.

์žฅ์ ์ด๋ผ๊ณ  ํ•œ๋‹ค๋ฉด, ์™ธ๋ถ€์—์„œ getter๋ฅผ ํ†ตํ•ด ๊ฐ’์„ ์ ‘๊ทผํ•˜์ง€ ์•Š๊ณ  ๋‚ด๋ถ€์˜ ํ•„๋“œ๊ฐ’์„ ํ†ตํ•ด์„œ ๋ฐ”๋กœ DTO๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์žฅ์ ์ด ์žˆ์„ ๊ฒƒ ๊ฐ™์•„์š”. (getter๋ฅผ ์ง€์–‘ํ•œ๋‹ค๋Š” ๊ด€์  ํ•˜์—์„œ...! ์ด ๋ถ€๋ถ„์€ ์ƒ๊ฐํ•ด๋ด์•ผ ๋  ๋ฌธ์ œ ๊ฐ™์•„์š”. ์ง€๊ธˆ๊นŒ์ง€ ๋„ˆ๋ฌด getter๋ฅผ ๋ฌด์ž‘์ •์œผ๋กœ ์•ˆ ์“ฐ๋ ค๊ณ  ํ–ˆ๋˜ ๊ฒƒ ๊ฐ™์•„์„œ์š”. ใ…Žใ…Ž)

ํ•˜์ง€๋งŒ ์ „์ž์˜ ๊ฒฝ์šฐ๊ฐ€ ๋ฆฌํŒฉํ† ๋ง์ด ๋” ํ•„์š”ํ•œ ๋ถ€๋ถ„์ด๋ผ๊ณ  ์ƒ๊ฐ์ด ๋“ค์–ด์š”. ๋ณ„๋„์˜ ์„œ๋น„์Šค ๊ณ„์ธต์„ ๋งŒ๋“ค์–ด์„œ DTO๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ํ•˜๊ณ , ์ด ๊ฒฐ๊ณผ๋ฅผ ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ์‚ฌ์šฉํ•˜๋„๋ก ํ•˜๋Š” ๊ฒŒ ๋” ์ข‹์€ ๊ตฌ์กฐ๊ฐ€ ์•„๋‹๊นŒ… ๋ผ๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ์–ด์š”. ๋ฆฌํŒฉํ† ๋ง ํ•˜๋ฉด์„œ ํ•œ ๋ฒˆ ์ˆ˜์ •ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค! ๐Ÿ˜Š

๊ทธ๋ž˜์„œ 2์ฐจ ๋ฆฌํŒฉํ† ๋ง ์‹œ, ์„œ๋น„์Šค ๊ณ„์ธต์„ ํ™œ์šฉํ•˜์—ฌ DTO๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ์ƒ์„ฑํ•˜์˜€๋‹ค. (ํ•˜์ง€๋งŒ, ์ง€๊ธˆ ์™€์„œ ์ƒ๊ฐํ•ด๋ณด๋ฉด ๊ทธ๋ƒฅ getter๋กœ ๋„๋ฉ”์ธ ๊ฐ์ฒด ์ž์ฒด๋ฅผ ๋„˜๊ฒจ์ฃผ๊ณ  ๋ทฐ์—์„œ ์ฒ˜๋ฆฌํ•˜๋„๋ก ํ•˜๋Š” ๊ฒŒ ๋” ๊น”๋”ํ–ˆ์„ ๊ฒƒ ๊ฐ™๋‹ค. ใ…Žใ…Ž ์ง€๊ธˆ ์ƒํƒœ๋กœ๋Š” ๋„ˆ๋ฌด ํ—ค๋น„ํ•œ ๋กœ์ง์ด๋ผ๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ๋‹ค.)

 

 

๐Ÿ’ฌ Getter๋ฅผ ์ง€์–‘ํ•˜๋Š” ์ด์œ 

๋‹น์‹œ ๊ตฌํ˜„ํ•  ๋•Œ ๋„๋ฉ”์ธ์˜ getter๋ฅผ ๊ต‰์žฅํžˆ ์ง€์–‘ํ•˜๋ ค๊ณ  ํ–ˆ์—ˆ๋‹ค. ์ฒ˜์Œ์—๋Š” ๋ณ„์ด์œ  ์—†์ด 'getter๋ฅผ ์ง€์–‘ํ•ด์•ผ ๋ผ!'๋ผ๋Š” ๋ง ํ•œ ๋งˆ๋””๋งŒ ๋“ฃ๊ณ , ๋ฆฌ๋ทฐ์–ด๋‹˜๊ป˜ ์งˆ๋ฌธ์„ ๋“ฃ๊ณ  ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฐ๋ก ์„ ๋‚ด๋ ธ์—ˆ๋‹ค.

๊ฐ์ฒด๋ฅผ ๋” ๊ฐ์ฒด์Šค๋Ÿฝ๊ฒŒ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š”, ๊ฐ์ฒด์—๊ฒŒ ๊ฐ’์„ ๋ฐ›์•„์˜ค๋Š” ๊ฒƒ์ด ์•„๋‹Œ ๊ฐ์ฒด์—๊ฒŒ ์ง์ ‘ ์งˆ๋ฌธ์„ ๋˜์ง€๋Š” ํ˜•ํƒœ๋กœ ์ด๋ฃจ์–ด์ ธ์•ผ ๋œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๊ธฐ ๋•Œ๋ฌธ์ด์—์š”. ๊ฐ์ฒด๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ฐ’์„ ๊ฐ์ฒด ์Šค์Šค๋กœ ํŒ๋‹จํ•˜๊ณ , ์™ธ๋ถ€์— ๋Œ€ํ•ด์„œ ์ตœ๋Œ€ํ•œ ์˜ํ–ฅ์„ ๋œ ๋ฐ›๋„๋ก ํ•˜๊ณ  ์‹ถ์–ด์„œ getter / setter๋ฅผ ์ง€์–‘ํ•˜๋ ค๊ณ  ํ•˜๋Š” ํŽธ์ด์—์š”.

ํ•˜์ง€๋งŒ, ์ƒ๊ฐํ•ด ๋ณด๋‹ˆ๊นŒ ๋ฌด์ž‘์ •์œผ๋กœ getter๋ฅผ ์ง€์–‘ํ•˜๋Š” ๊ฒƒ๋„ ๋ณ„๋กœ ์ข‹์€ ์„ค๊ณ„๋ผ๋Š” ์ƒ๊ฐ์ด ๋“ค์ง€ ์•Š์•˜์–ด์š”. ํŠนํžˆ ์ด์ „์ฒ˜๋Ÿผ getter๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ธฐ ์œ„ํ•ด์„œ ๋„๋ฉ”์ธ ๋‹จ์—์„œ DTO๋ฅผ ๋ฆฌํ„ดํ•˜๋Š” ๋“ฑ์˜ ํ–‰์œ„๋Š” ์˜คํžˆ๋ ค ๊ฐ์ฒด ๊ฐ„์˜ ๊ฒฐํ•ฉ๋„๋ฅผ ์ฆ๊ฐ€์‹œํ‚ค๋Š” ํ–‰์œ„๋ผ๊ณ  ์ƒ๊ฐ์ด ๋“ค์—ˆ์–ด์š”...! ๊ทธ๋ž˜์„œ ์ €๋งŒ์˜ ์ž‘์€ ๊ธฐ์ค€์„ ์„ธ์› ๋Š”๋ฐ, ์ถœ๋ ฅ์„ ์œ„ํ•ด ํ•„์š”ํ•˜๊ฑฐ๋‚˜ DTO ๋ณ€ํ™˜ ๋“ฑ์—์„œ๋Š” getter์˜ ์‚ฌ์šฉ์ด ํ•„์ˆ˜์ ์ด๋ผ๊ณ  ์ƒ๊ฐ์ด ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๋Ÿฐ ๊ฒฝ์šฐ์—๋Š” ์‚ฌ์šฉํ•˜๋Š” ๊ฒŒ ๋” ๋‚ซ๋‹ค๊ณ  ์ƒ๊ฐ์ด ๋“ค์–ด์š”!

๊ทธ๋ž˜์„œ ์ด๋ฒˆ ๋ฆฌํŒฉํ† ๋ง ๋•Œ๋Š” cars์— ๋Œ€ํ•œ getter๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด์„œ DTO ์ƒ์„ฑ์„ ๋„๋ฉ”์ธ์—์„œ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š๋„๋ก ๋ณ€๊ฒฝํ•˜์˜€์–ด์š”. ๋˜ํ•œ, unmodifableList๋ฅผ ํ†ตํ•ด์„œ ์™ธ๋ถ€์—์„œ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๋„๋ก ์ง„ํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค! ๐Ÿ˜Š ์ด๋Ÿฐ ์‹์œผ๋กœ getter๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฑด ๊ดœ์ฐฎ์„๊นŒ์š”?

1์ฐจ ๋ฏธ์…˜์„ ์™„์ „ํžˆ ๋๋‚ธ ์ง€๊ธˆ์€, DTO๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ตฌ์กฐ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์ง€๋งŒ ๋‹น์‹œ์— ๋‚ด๋ฆด ์ˆ˜ ์žˆ๋˜ ์ตœ์„ ์˜ ๊ฒฐ๋ก ์ด์—ˆ๋˜ ๊ฒƒ ๊ฐ™๋‹ค.

 


โœ”๏ธ 2์ฐจ ๋ฆฌํŒฉํ„ฐ๋ง

2์ฐจ ๋ฆฌํŒฉํ„ฐ๋ง์—์„œ๋Š” ๊ธฐ๊ฐ„์ด ๊ทธ๋ ‡๊ฒŒ ๊ธธ์ง€ ์•Š์•˜์–ด์„œ, ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ˆ˜์ •ํ•˜์˜€๋‹ค.

- ๋„๋ฉ”์ธ์—์„œ DTO๋ฅผ ์ฐธ์กฐํ•˜์ง€ ์•Š๋„๋ก ๊ฐœ์„ ํ•˜๊ธฐ.
- Cars / Race์— ๋Œ€ํ•œ Service Layer ์ถ”๊ฐ€ํ•˜๊ธฐ. (์ปจํŠธ๋กค๋Ÿฌ์—์„œ ๋„๋ฉ”์ธ ๋Œ€์‹  ์„œ๋น„์Šค๋ฅผ ์ฐธ์กฐํ•˜๋„๋ก ๋ณ€๊ฒฝํ•˜๊ธฐ)
- ํ•˜๋‚˜์˜ ๋ฉ”์„œ๋“œ๋Š” ํ•˜๋‚˜์˜ ์ผ๋งŒ ํ•˜๋„๋ก ๋ถ„๋ฆฌํ•˜๊ธฐ, ๋ณ€์ˆ˜๋ช… ๋ฆฌํŒฉํ† ๋ง ํ•˜๊ธฐ.
- ์„œ๋น„์Šค์— ๋Œ€ํ•œ ํ…Œ์ŠคํŠธ ์ถ”๊ฐ€ ๋ฐ ๋„๋ฉ”์ธ์˜ ๋ชจ๋“  public ๋ฉ”์„œ๋“œ์— ๋Œ€ํ•œ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ์ง„ํ–‰ํ•˜๊ธฐ.
- ์ž๋™์ฐจ์— ๋Œ€ํ•œ Comparable ์ธํ„ฐํŽ˜์ด์Šค ๊ตฌํ˜„์„ ํ†ตํ•ด position ๊ตฌํ•˜๋Š” ๋กœ์ง ๊ฐœ์„ ํ•˜๊ธฐ. (getter ์‚ฌ์šฉ X) 

DTO ๋ณ€ํ™˜์„ ์œ„ํ•ด์„œ Service ๋ ˆ์ด์–ด๋ฅผ ์ถ”๊ฐ€ํ•˜์˜€๋‹ค๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ํฌ๊ฒŒ ๋ฐ”๋€ ์ ์ด๋‹ค. ๊ทธ๋ฆฌ๊ณ , ๋‹น์‹œ ๋ฆฌ๋ทฐ์–ด๋‹˜๊ป˜ ๋ฐ›์•˜๋˜ ํ”ผ๋“œ๋ฐฑ ์ค‘์—์„œ "๋ถ€์ •ํ˜• ๋„ค์ด๋ฐ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ธฐ" ์— ๋Œ€ํ•ด์„œ ๋ฆฌ๋ทฐ๋ฅผ ๋ฐ›์•˜์—ˆ๋Š”๋ฐ, ์ด ๋ถ€๋ถ„๋„ ์ž์ž˜ํ•˜๊ฒŒ ์ˆ˜์ •ํ–ˆ๋˜ ์ ์ด ๊ธฐ์–ต์— ๋‚จ๋Š”๋‹ค. ๊ทธ๋ฆฌ๊ณ , ์—ฌ์ „ํžˆ ํ•œ ๊ฐ€์ง€ ๋ฉ”์„œ๋“œ๋Š” ํ•˜๋‚˜์˜ ํ–‰์œ„๋ฅผ ํ•˜๋„๋ก ๋งŒ๋“œ๋Š” ๊ฒŒ ์ž˜ ์ง€์ผœ์ง€์ง€ ์•Š์•„์„œ, ๋ฆฌํŒฉํ† ๋ง ๋•Œ ์ตœ๋Œ€ํ•œ ๊ฐœ์„ ํ•˜๋ ค๊ณ  ๋…ธ๋ ฅํ–ˆ๋‹ค.

 

๐Ÿ’ฌ for๋ฌธ๊ณผ for-each, stream

// Cars.java
cars.forEach(car -> {
        int power = numberGenerator.generate();
        car.move(power);
        });

๋˜ํ•œ, ํŽ˜์–ด๋ž‘ ์ง„ํ–‰ํ•˜๋ฉด์„œ for๋ฌธ ๋Œ€์‹ ์— .forEach()๋ฅผ ์‚ฌ์šฉํ–ˆ์—ˆ๋Š”๋ฐ, ์ด ๋ถ€๋ถ„์— ๋Œ€ํ•ด ์ •ํ™•ํžˆ ์ธ์ง€ํ•˜์ง€ ๋ชปํ•˜๊ณ  ์‚ฌ์šฉํ–ˆ๋˜ ๊ฒƒ ๊ฐ™์•„์„œ ๋”ฐ๋กœ ๊ณต๋ถ€๋ฅผ ์ง„ํ–‰ํ–ˆ๋‹ค.

๋‚ด๋ถ€์—์„œ iterator๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๊ฐ’์„ ๊ฐ€์ ธ์˜จ๋‹ค๋Š” ์ ๊ณผ, for-each๊ฐ€ ์ผ๋ฐ˜ for์— ๋น„ํ•ด์„œ ๋Š๋ฆฌ๋‹ค๋Š” ๊ฒƒ์€ ์ฒ˜์Œ ์•Œ์•˜๋‹ค ๐Ÿซข ๋˜ํ•œ, Collections.forEach ์—ญ์‹œ iterator๋ฅผ ์‚ฌ์šฉํ•˜๋ฉฐ ๋ฐ˜๋ณตํ•˜๊ธฐ ๋•Œ๋ฌธ์—, enhanced for๋ฌธ๊ณผ ๋™์ผํ•˜๊ณ , ์„ฑ๋Šฅ์ƒ์œผ๋กœ ๋™์ผํ•˜๋‹ค๊ณ  ํ•œ๋‹ค! (Stream์ด๋ผ์„œ ๋” ๋Š๋ฆด ์ค„ ์•Œ์•˜๋Š”๋ฐ ์•„๋‹ˆ์—ˆ๋‹ค...) ์ด๋ ‡๊ฒŒ ๋˜ ๋ฐฐ์šธ ์ˆ˜ ์žˆ์—ˆ๋‹ค.

 


โœ”๏ธ 3์ฐจ ๋ฆฌํŒฉํ„ฐ๋ง

์‚ฌ์‹ค 3์ฐจ ๋ฆฌํŒฉํ„ฐ๋ง์€ ๋งŽ์ด ์ง„ํ–‰ํ•˜์ง€ ๋ชปํ–ˆ๋‹ค. ์—ฐ๊ทน๋„ ๊ฒน์น˜๊ณ , ๋‹ค์Œ ๋‚ ์— ์ƒˆ๋กœ์šด ๋ฏธ์…˜์„ ์ง„ํ–‰ํ•ด์•ผ ๋ผ์„œ ํฌ๊ฒŒ ๋ฐ”๊พธ์ง€๋Š” ๋ชปํ–ˆ๋‹ค.

 

๐Ÿ’ฌ ์šฐ์Šน์ž ์„ ์ถœ ๋กœ์ง์— ๋Œ€ํ•˜์—ฌ

 public List<String> pickWinners() {
        Car maxPositionCar = getMaxPositionCar();

        return cars.stream()
        .filter(maxPositionCar::isSamePosition)
        .map(Car::getName)
        .collect(Collectors.toUnmodifiableList());
        }

๊ธฐ์กด์—๋Š” Cars์—์„œ ์šฐ์Šน์ž๋ฅผ ๋ฝ‘๋Š” ๋กœ์ง์„ ๋‘์—ˆ์—ˆ๋‹ค. ์ด์œ ๋Š” ์ผ๊ธ‰์ปฌ๋ ‰์…˜์ธ Cars์—์„œ ์ด๋ฏธ ์ž๋™์ฐจ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ๊ฐ์ฒด์—๊ฒŒ ์งˆ๋ฌธํ•˜๊ธฐ ์œ„ํ•ด์„œ ์ž๋™์ฐจ ๋‚ด์—์„œ ์ง„ํ–‰ํ•˜๊ณ ์ž ํ–ˆ์—ˆ๋‹ค. (getter๋ฅผ ํ†ตํ•ด ๋ฐ›์•„์™€์„œ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š์œผ๋ ค๊ณ  ํ–ˆ์—ˆ๋‹ค.) ๋‹ค๋งŒ, ๋ฆฌ๋ทฐ์–ด๋‹˜๊ป˜์„œ๋Š” '์šฐ์Šน์ž ์„ ์ถœ์— ๋Œ€ํ•œ ์ฑ…์ž„'์€ ๊ฒฝ์ฃผ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” Race์—์„œ ์ด๋ฃจ์–ด์ง€๋Š” ๊ฒŒ ๋” ๋งž์ง€ ์•Š๋ƒ๊ณ  ๋ง์”€ํ•ด ์ฃผ์…”์„œ, WinnerCar๋ผ๋Š” ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ด์„œ ๊ด€๋ฆฌํ•˜๊ณ ์ž ํ–ˆ๋‹ค.

public class WinnerCar {

    private final Cars carInfo;

    private WinnerCar(final Cars carInfo) {
        this.carInfo = carInfo;
    }

    public static WinnerCar create(Cars carInfo) {
        return new WinnerCar(carInfo);
    }

    public List<String> getName() {
        Car maxPositionCar = carInfo.getMaxPositionCar();
        return getWinnerNames(maxPositionCar);
    }

    private List<String> getWinnerNames(Car maxPositionCar) {
        return carInfo.getCars()
                .stream()
                .filter(maxPositionCar::isSamePosition)
                .map(Car::getName)
                .collect(Collectors.toUnmodifiableList());
    }
}

๋‹ค๋งŒ, ๋‚ด๋ถ€์ ์œผ๋กœ Cars์˜ ์ •๋ณด๋ฅผ ๋ฐ›์•„์™€์„œ ์ˆ˜ํ–‰ํ•˜๊ธฐ ๋•Œ๋ฌธ์— WinnerCar๊ฐ€ ํŠน๋ณ„ํžˆ ํ•„์š”ํ•˜๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ค์ง€ ์•Š์•„์„œ, ์ตœ์ข…์ ์œผ๋กœ ๋ดค์„ ๋•Œ๋Š” ๊ทธ๋ ‡๊ฒŒ ์ข‹์€ ๋ฆฌํŒฉํ† ๋ง์ด ์•„๋‹ˆ์—ˆ๋‹ค๊ณ  ์ƒ๊ฐ์ด ๋“ ๋‹ค. (์•„๋ฌด๋ž˜๋„ ์‹œ๊ฐ„์ด ์ด‰๋ฐ•ํ•ด์„œ ๋” ์‹ ๊ฒฝ์„ ๋ชป ์“ด ๊ฒƒ ๊ฐ™๋‹ค ใ… ใ… ) ์ง€๊ธˆ ์ง„ํ–‰ํ•œ๋‹ค๋ฉด, maxPosition์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๊ด€๋ฆฌํ•˜๊ฑฐ๋‚˜, ํ˜น์€ ์šฐ์Šน์ž์— ๋Œ€ํ•ด ๋”ฐ๋กœ ์ €์žฅํ•˜๋Š” ํ•„๋“œ๋ฅผ ๋‘์–ด์„œ ์กฐ๊ธˆ ๋” ๊ฐ์ฒด๊ฐ€ ์ฑ…์ž„์„ ๊ฐ€์ง€๋„๋ก ์ง„ํ–‰ํ–ˆ์„ ๊ฒƒ ๊ฐ™๋‹ค. ์ด ๋ถ€๋ถ„์€ ์•„์‰ฝ๋‹ค.


 

์•„๋ฌดํŠผ, ์ด๋ ‡๊ฒŒ ํšŒ๊ณ  ์ž‘์„ฑ์ด ๋๋‚ฌ๋‹ค! ๐Ÿฅฒ

๋ณธ ํšŒ๊ณ ์— ๋‹ด๊ธด ๊ฒƒ๋ณด๋‹ค ์‚ฌ์‹ค ๋” ๋งŽ์€ ๊ฒƒ๋“ค์„ ํ–ˆ๋˜ ๊ฒƒ ๊ฐ™์ง€๋งŒ, ๊ทธ๋Ÿฐ ๊ฑด PR์—์„œ ์ถฉ๋ถ„ํžˆ ๋“œ๋Ÿฌ๋‚˜๋Š” ์ •๋ณด์ธ ๊ฒƒ ๊ฐ™์•„์„œ ์กฐ๊ธˆ ๋” ๋‚ด ๊ฐ์ •๊ณผ ๋ฐฐ์šด ์ ๋“ค์„ ์œ„์ฃผ๋กœ ์ž‘์„ฑํ•˜์˜€๋‹ค. ์•ž์œผ๋กœ ๋ฏธ์…˜ํ•˜๋ฉด์„œ ํšŒ๊ณ ๋„ ๊พธ์ค€ํžˆ ์ž‘์„ฑํ•ด๋ณด๊ณ ์ž ํ•œ๋‹ค ๐Ÿ’ช ํŒŒ์ดํŒ…...!

Comments