๋ณธ๋ฌธ์œผ๋กœ ๊ฑด๋„ˆ๋›ฐ๊ธฐ

๐Ÿญ Chapter 4: ์ฃผ์„

๋‚˜์œ ์ฝ”๋“œ์— ์ฃผ์„์„ ๋‹ฌ์ง€ ๋งˆ๋ผ. ์ƒˆ๋กœ ์งœ๋ผ.

์ž˜ ๋‹ฌ๋ฆฐ ์ฃผ์„์€ ๊ทธ ์–ด๋–ค ์ •๋ณด๋ณด๋‹ค ์œ ์šฉํ•˜๋‹ค. ๊ฒฝ์†”ํ•˜๊ณ  ๊ทผ๊ฑฐ ์—†๋Š” ์ฃผ์„์€ ์ฝ”๋“œ๋ฅผ ์ดํ•ดํ•˜๊ธฐ ์–ด๋ ต๊ฒŒ ๋งŒ๋“ ๋‹ค. ์˜ค๋ž˜๋˜๊ณ  ์กฐ์žกํ•œ ์ฃผ์„์€ ๊ฑฐ์ง“๊ณผ ์ž˜๋ชป๋œ ์ •๋ณด๋ฅผ ํผ๋œจ๋ ค ํ•ด์•…์„ ๋ฏธ์นœ๋‹ค.

์šฐ๋ฆฌ๋Š” ์ฝ”๋“œ๋กœ ์˜๋„๋ฅผ ํ‘œํ˜„ํ•˜์ง€ ๋ชปํ•ด, ๊ทธ๋Ÿฌ๋‹ˆ๊นŒ ์‹คํŒจ๋ฅผ ๋งŒํšŒํ•˜๊ธฐ ์œ„ํ•ด ์ฃผ์„์„ ์‚ฌ์šฉํ•œ๋‹ค. ์ฃผ์„์€ ์–ธ์ œ๋‚˜ ์‹คํŒจ๋ฅผ ์˜๋ฏธํ•œ๋‹ค. ๋•Œ๋•Œ๋กœ ์ฃผ์„ ์—†์ด๋Š” ์ž์‹ ์„ ํ‘œํ˜„ํ•œ ๋ฐฉ๋ฒ•์„ ์ฐพ์ง€ ๋ชปํ•ด ํ•  ์ˆ˜ ์—†์ด ์ฃผ์„์„ ์‚ฌ์šฉํ•œ๋‹ค. ๊ทธ๋ž˜์„œ ์ฃผ์„์€ ๋ฐ˜๊ฒจ ๋งž์€ ์†๋‹˜์ด ์•„๋‹ˆ๋‹ค.

์ฃผ์„์€ ์˜ค๋ž˜๋ ์ˆ˜๋ก ์ฝ”๋“œ์—์„œ ๋ฉ€์–ด์ง„๋‹ค. ์˜ค๋ž˜๋ ์ˆ˜๋ก ์™„์ „ํžˆ ๊ทธ๋ฆ‡๋  ๊ฐ€๋Šฅ์„ฑ๋„ ์ปค์ง„๋‹ค. ์ด์œ ๋Š” ๋‹จ์ˆœํ•˜๋‹ค. ํ”„๋กœ๊ทธ๋ž˜๋จธ๋“ค์ด ์ฃผ์„์„ ์œ ์ง€ํ•˜๊ณ  ๋ณด์ˆ˜ํ•˜๊ธฐ๋ž€ ํ˜„์‹ค์ ์œผ๋กœ ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ˆ๊นŒ.

์ฝ”๋“œ๋Š” ๋ณ€ํ™”ํ•˜๊ณ  ์ง„ํ™”ํ•œ๋‹ค. ์ผ๋ถ€๊ฐ€ ์—ฌ๊ธฐ์„œ ์ €๊ธฐ๋กœ ์˜ฎ๊ฒจ์ง€๊ธฐ๋„ ํ•œ๋‹ค. ์กฐ๊ฐ์ด ๋‚˜๋‰˜๊ณ  ๊ฐˆ๋ผ์ง€๊ณ  ํ•ฉ์ณ์ง€๋ฉด์„œ ๊ดด๋ฌผ๋กœ ๋ณ€ํ•œ๋‹ค. ๋ถˆํ–‰ํ•˜๊ฒŒ๋„ ์ฃผ์„์ด ์–ธ์ œ๋‚˜ ์ฝ”๋“œ๋ฅผ ๋”ฐ๋ผ๊ฐ€์ง€๋Š” ์•Š๋Š”๋‹ค. ์•„๋‹ˆ, ๋”ฐ๋ผ๊ฐ€์ง€ ๋ชปํ•œ๋‹ค. ์ฃผ์„์ด ์ฝ”๋“œ์—์„œ ๋ถ„๋ฆฌ๋˜์–ด ์ ์  ๋” ๋ถ€์ •ํ™•ํ•œ ๊ณ ์•„๋กœ ๋ณ€ํ•˜๋Š” ์‚ฌ๋ก€๊ฐ€ ๋„ˆ๋ฌด๋„ ํ”ํ•˜๋‹ค.

๋ถ€์ •ํ™•ํ•œ ์ฃผ์„์€ ์•„์˜ˆ ์—†๋Š” ์ฃผ์„๋ณด๋‹ค ํ›จ์”ฌ ๋” ๋‚˜์˜๋‹ค. ๋ถ€์ •ํ™•ํ•œ ์ฃผ์„์€ ๋…์ž๋“ค์„ ํ˜„ํ˜นํ•˜๊ณ  ์˜ค๋„ํ•œ๋‹ค. ๋ถ€์ •ํ™•ํ•œ ์ฃผ์„์€ ๊ฒฐ์ฝ” ์ด๋ค„์ง€์ง€ ์•Š์„ ๊ธฐ๋Œ€๋ฅผ ์‹ฌ์–ด์ค€๋‹ค. ๋” ์ด์ƒ ์ง€ํ‚ฌ ํ•„์š”๊ฐ€ ์—†๋Š” ๊ทœ์น™์ด๋‚˜ ์ง€์ผœ์„œ๋Š” ์•ˆ ๋˜๋Š” ๊ทœ์น™์„ ๋ช…์‹œํ•œ๋‹ค.

์ง„์‹ค์€ ํ•œ๊ณณ์—๋งŒ ์กด์žฌํ•œ๋‹ค. ๋ฐ”๋กœ ์ฝ”๋“œ๋‹ค. ์ฝ”๋“œ๋งŒ์ด ์ž๊ธฐ๊ฐ€ ํ•˜๋Š” ์ผ์„ ์ง„์‹ค๋˜๊ฒŒ ๋งํ•œ๋‹ค. ์ฝ”๋“œ๋งŒ์ด ์ •ํ™•ํ•œ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•˜๋Š” ์œ ์ผํ•œ ์ถœ์ฒ˜๋‹ค. ๊ทธ๋Ÿฌ๋ฏ€๋กœ ์šฐ๋ฆฌ๋Š” ์ฃผ์„์„ ๊ฐ€๋Šฅํ•œ ์ค„์ด๋„๋ก ๊พธ์ค€ํžˆ ๋…ธ๋ ฅํ•ด์•ผ ํ•œ๋‹ค.

๐ŸŽƒ ์ฃผ์„์€ ๋‚˜์œ ์ฝ”๋“œ๋ฅผ ๋ณด์™„ํ•˜์ง€ ๋ชปํ•œ๋‹คโ€‹

์ฝ”๋“œ์— ์ฃผ์„์„ ์ถ”๊ฐ€ํ•˜๋Š” ์ผ๋ฐ˜์ ์ธ ์ด์œ ๋Š” ์ฝ”๋“œ ํ’ˆ์งˆ์ด ๋‚˜์˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

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

๐ŸŽƒ ์ฝ”๋“œ์˜ ์˜๋„๋ฅผ ํ‘œํ˜„ํ•˜๋ผ!โ€‹

ํ™•์‹คํžˆ ์ฝ”๋“œ๋งŒ์œผ๋กœ ์˜๋„๋ฅผ ์„ค๋ช…ํ•˜๊ธฐ ์–ด๋ ค์šด ๊ฒฝ์šฐ๊ฐ€ ์กด์žฌํ•œ๋‹ค. ๋ถˆํ–‰ํžˆ๋„ ๋งŽ์€ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ด๋ฅผ ์ฝ”๋“œ๋Š” ํ›Œ๋ฅญํ•œ ์ˆ˜๋‹จ์ด ์•„๋‹ˆ๋ผ๋Š” ์˜๋ฏธ๋กœ ํ•ด์„ํ•œ๋‹ค. ๋ถ„๋ช…ํžˆ ์ž˜๋ชป๋œ ์ƒ๊ฐ์ด๋‹ค. ๋‹ค์Œ ์ฝ”๋“œ ์˜ˆ์ œ ๋‘ ๊ฐœ๋ฅผ ์‚ดํŽด๋ณด์ž. ์–ด๋Š ์ชฝ์ด ๋” ๋‚˜์€๊ฐ€?

if ((employee.flags & HOURLY_FLAG) && (employee.age > 65))

๋‹ค์Œ ์ฝ”๋“œ๋Š” ์–ด๋–ค๊ฐ€?

if (employee.isEligibleForFullBenefits())

๋ช‡ ์ดˆ๋งŒ ๋” ์ƒ๊ฐํ•˜๋ฉด ์ฝ”๋“œ๋กœ ๋Œ€๋‹ค์ˆ˜ ์˜๋„๋ฅผ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋งŽ์€ ๊ฒฝ์šฐ ์ฃผ์„์œผ๋กœ ๋‹ฌ๋ ค๋Š” ์„ค๋ช…์„ ํ•จ์ˆ˜๋กœ ๋งŒ๋“ค์–ด ํ‘œํ˜„ํ•ด๋„ ์ถฉ๋ถ„ํ•˜๋‹ค.

๐ŸŽƒ ์ข‹์€ ์ฃผ์„โ€‹

์–ด๋–ค ์ฃผ์„์€ ํ•„์š”ํ•˜๊ฑฐ๋‚˜ ์œ ์ตํ•˜๋‹ค. ํ•˜์ง€๋งŒ ๋ช…์‹ฌํ•˜๊ธฐ ๋ฐ”๋ž€๋‹ค. ์ •๋ง๋กœ ์ข‹์€ ์ฃผ์„์€, ์ฃผ์„์„ ๋‹ฌ์ง€ ์•Š์€ ๋ฐฉ๋ฒ•์„ ์ฐพ์•„๋‚ธ ์ฃผ์„์ด๋ผ๋Š” ์‚ฌ์‹ค์„!

๐ŸŽˆ ๋ฒ•์ ์ธ ์ฃผ์„โ€‹

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

์†Œ์Šค ํŒŒ์ผ ์ฒซ๋จธ๋ฆฌ์— ๋“ค์–ด๊ฐ€๋Š” ์ฃผ์„์ด ๋ฐ˜๋“œ์‹œ ๊ณ„์•ฝ ์กฐ๊ฑด์ด๋‚˜ ๋ฒ•์ ์ธ ์ •๋ณด์ผ ํ•„์š”๋Š” ์—†๋‹ค. ๋ชจ๋“  ์กฐํ•ญ๊ณผ ์กฐ๊ฑด์„ ์—ด๊ฑฐํ•˜๋Š” ๋Œ€์‹ ์—, ๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด, ํ‘œ์ค€ ๋ผ์ด์„ ์Šค๋‚˜ ์™ธ๋ถ€ ๋ฌธ์„œ๋ฅผ ์ฐธ์กฐํ•ด๋„ ๋˜๊ฒ ๋‹ค.

๐ŸŽˆ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•˜๋Š” ์ฃผ์„โ€‹

๋•Œ๋กœ๋Š” ๊ธฐ๋ณธ์ ์ธ ์ •๋ณด๋ฅผ ์ฃผ์„์œผ๋กœ ์ œ๊ณตํ•˜๋ฉด ํŽธ๋ฆฌํ•˜๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋‹ค์Œ ์ฃผ์„์€ ์ถ”์ƒ ๋ฉ”์„œ๋“œ๊ฐ€ ๋ฐ˜ํ™˜ํ•  ๊ฐ’์„ ์„ค๋ช…ํ•œ๋‹ค.

// ํ…Œ์ŠคํŠธ ์ค‘์ธ Responder ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
protected abstract Responder responderInstance();

๋•Œ๋•Œ๋กœ ์œ„์™€ ๊ฐ™์€ ์ฃผ์„์ด ์œ ์šฉํ•˜๋‹ค ํ• ์ง€๋ผ๋„, ๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด, ํ•จ์ˆ˜ ์ด๋ฆ„์— ์ •๋ณด๋ฅผ ๋‹ด๋Š” ํŽธ์ด ๋” ์ข‹๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์œ„ ์ฝ”๋“œ๋Š” ํ•จ์ˆ˜ ์ด๋ฆ„์„ responderBeingTested๋กœ ๋ฐ”๊พธ๋ฉด ์ฃผ์„์ด ํ•„์š” ์—†์–ด์ง„๋‹ค.

๋‹ค์Œ์€ ์ข€ ๋” ๋‚˜์€ ์˜ˆ์ œ๋‹ค.

// kk:mm:ss EEE, MMM dd, yyyy ํ˜•์‹์ด๋‹ค.
Pattern timeMatcher = Pattern.compile(
"\\d*:\\d*:\\d* \\w*, \\w* \\d*, \\d*"
);

์œ„์— ์ œ์‹œํ•œ ์ฃผ์„์€ ์ฝ”๋“œ์—์„œ ์‚ฌ์šฉํ•œ ์ •๊ทœํ‘œํ˜„์‹์ด ์‹œ๊ฐ๊ณผ ๋‚ ์งœ๋ฅผ ๋œปํ•œ๋‹ค๊ณ  ์„ค๋ช…ํ•œ๋‹ค. ์ด์™•์ด๋ฉด ์‹œ๊ฐ๊ณผ ๋‚ ์งœ๋ฅผ ๋ณ€ํ™˜ํ•˜๋Š” ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์–ด ์ฝ”๋“œ๋ฅผ ์˜ฎ๊ฒจ์ฃผ๋ฉด ๋” ์ข‹๊ณ  ๋” ๊น”๋”ํ•˜๊ฒ ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ์ฃผ์„์ด ํ•„์š” ์—†์–ด์ง„๋‹ค.

๐ŸŽˆ ์˜๋„๋ฅผ ์„ค๋ช…ํ•˜๋Š” ์ฃผ์„โ€‹

๋•Œ๋•Œ๋กœ ์ฃผ์„์€ ๊ตฌํ˜„์„ ์ดํ•ดํ•˜๊ฒŒ ๋„์™€์ฃผ๋Š” ์„ ์„ ๋„˜์–ด ๊ฒฐ์ •์— ๊น”๋ฆฐ ์˜๋„๊นŒ์ง€ ์„ค๋ช…ํ•œ๋‹ค.

public void testConcurrentAddWidgets() throws Exception {
WidgetBuilder widgetBuilder =new WidgetBuilder(new Class[]{BoldWidget.class});

String text = "'''bold text'''";
ParentWidget parent = new BoldWidget(new MockWidgetRoot(), "'''bold text'''");
AtomicBoolean failFlag = new AtomicBoolean();
failFlag.set(false);

// ์Šค๋ ˆ๋“œ๋ฅผ ๋Œ€๋Ÿ‰ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ ์–ด๋–ป๊ฒŒ๋“  ๊ฒฝ์Ÿ ์กฐ๊ฑด์„ ๋งŒ๋“ค๋ ค ์‹œ๋„ํ•œ๋‹ค.
for (int i = 0; i < 25000; i++) {
WidgetBuilderThread widgetBuilderThread = new WidgetBuilderThread(widgetBuilder, text, parent, failFlag);
Thread thread = new Thread(widgetBuilderThread);
thread.start();
}

assertEquals(false, failFlag.get());
}

๐ŸŽˆ ์˜๋ฏธ๋ฅผ ๋ช…๋ฃŒํ•˜๊ฒŒ ๋ฐํžˆ๋Š” ์ฃผ์„โ€‹

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

public void testCompareTo() throws Exception {
WikiPagePath a = PathParser.parse("PageA");

assertTrue(a.compareTo(a) == 0); // a == b
}

๋ฌผ๋ก  ๊ทธ๋ฆ‡๋œ ์ฃผ์„์„ ๋‹ฌ์•„๋†“์„ ์œ„ํ—˜์€ ์ƒ๋‹นํžˆ ๋†’๋‹ค.

๐ŸŽˆ ๊ฒฐ๊ณผ๋ฅผ ๊ฒฝ๊ณ ํ•˜๋Š” ์ฃผ์„โ€‹

๋•Œ๋กœ ๋‹ค๋ฅธ ํ”„๋กœ๊ทธ๋ž˜๋จธ์—๊ฒŒ ๊ฒฐ๊ณผ๋ฅผ ๊ฒฝ๊ณ ํ•  ๋ชฉ์ ์œผ๋กœ ์ฃผ์„์„ ์‚ฌ์šฉํ•œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋‹ค์Œ์€ ํŠน์ • ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋ฅผ ๊บผ์•ผํ•˜๋Š” ์ด์œ ๋ฅผ ์„ค๋ช…ํ•˜๋Š” ์ฃผ์„์ด๋‹ค.

// ์—ฌ์œ  ์‹œ๊ฐ„์ด ์ถฉ๋ถ„ํ•˜์ง€ ์•Š๋‹ค๋ฉด ์‹คํ–‰ํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค.
public void _testWithReallyBigFile() {
writeLinesToFile(10000000);

response.setBody(testFile);
response.readToSend(this);
String responseString = output.toString();
assertSubString("Content-Length: 10000000", responseString);
assetTrue(bytesSent > 10000000);
}

๐ŸŽˆ TODO ์ฃผ์„โ€‹

๋•Œ๋กœ๋Š” '์•ž์œผ๋กœ ํ•  ์ผ'์„ //TODO ์ฃผ์„์œผ๋กœ ๋‚จ๊ฒจ๋‘๋ฉด ํŽธํ•˜๋‹ค. ๋‹ค์Œ์€ ํ•จ์ˆ˜๋ฅผ ๊ตฌํ˜„ํ•˜์ง€ ์•Š์€ ์ด์œ ์™€ ๋ฏธ๋ž˜ ๋ชจ์Šต์„ //TODO ์ฃผ์„์œผ๋กœ ์„ค๋ช…ํ•œ ์˜ˆ์ œ๋‹ค.

// TODO-MDM ํ˜„์žฌ ํ•„์š”ํ•˜์ง€ ์•Š๋‹ค.
// ์ฒดํฌ์•„์›ƒ ๋ชจ๋ธ์„ ๋„์ž…ํ•˜๋ฉด ํ•จ์ˆ˜๊ฐ€ ํ•„์š” ์—†๋‹ค.
protected VersionInfo makeVersion() throws Exception {
return null;
}

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

๐ŸŽˆ ์ค‘์š”์„ฑ์„ ๊ฐ•์กฐํ•˜๋Š” ์ฃผ์„โ€‹

์ž์ง“ ๋Œ€์ˆ˜๋กญ์ง€ ์•Š๋‹ค๊ณ  ์—ฌ๊ฒจ์งˆ ๋ญ”๊ฐ€์˜ ์ค‘์š”์„ฑ์„ ๊ฐ•์กฐํ•˜๊ธฐ ์œ„ํ•ด์„œ๋„ ์ฃผ์„์„ ์‚ฌ์šฉํ•œ๋‹ค.

String listItemContent = match.group(3).trim();
// ์—ฌ๊ธฐ์„œ trim์€ ์ •๋ง ์ค‘์š”ํ•˜๋‹ค. trim ํ•จ์ˆ˜๋Š” ๋ฌธ์ž์—ด์—์„œ ์‹œ์ž‘ ๊ณต๋ฐฑ์„ ์ œ๊ฑฐํ•œ๋‹ค.
// ๋ฌธ์ž์—ด์— ์‹œ์ž‘ ๊ณต๋ฐฑ์ด ์žˆ์œผ๋ฉด ๋‹ค๋ฅธ ๋ฌธ์ž์—ด๋กœ ์ธ์‹๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
new ListItemWidget(this, listItemContent, this.level + 1);
return buildList(text.substring(match.end()));

๐ŸŽˆ ๊ณต๊ฐœ API์—์„œ Javadocsโ€‹

์„ค๋ช…์ด ์ž˜ ๋œ ๊ณต๊ฐœ API๋Š” ์ฐธ์œผ๋กœ ์œ ์šฉํ•˜๊ณ  ๋งŒ์กฑ์Šค๋Ÿฝ๋‹ค. ํ‘œ์ค€ ์ž๋ฐ” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ์‚ฌ์šฉํ•œ Javadocs๊ฐ€ ์ข‹์€ ์˜ˆ๋‹ค. Javadocs๊ฐ€ ์—†๋‹ค๋ฉด ์ž๋ฐ” ํ”„๋กœ๊ทธ๋žจ์„ ์งœ๊ธฐ๊ฐ€ ์•„์ฃผ ์–ด๋ ค์šฐ๋ฆฌ๋ผ.

๊ณต๊ฐœ API๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค๋ฉด ๋ฐ˜๋“œ์‹œ ํ›Œ๋ฅญํ•œ Javadocs๋ฅผ ์ž‘์„ฑํ•œ๋‹ค. ํ•˜์ง€๋งŒ ์ด ์žฅ์—์„œ ์ œ์‹œํ•˜๋Š” ๋‚˜๋จธ์ง€ ์ถฉ๊ณ ๋„ ๋ช…์‹ฌํ•˜๊ธฐ ๋ฐ”๋ž€๋‹ค. ์—ฌ๋Š ์ฃผ์„๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ Javadocs ์—ญ์‹œ ๋…์ž๋ฅผ ์˜ค๋„ํ•˜๊ฑฐ๋‚˜, ์ž˜๋ชป ์œ„์น˜ํ•˜๊ฑฐ๋‚˜, ๊ทธ๋ฆ‡๋œ ์ •๋ณด๋ฅผ ์ „๋‹ฌํ•  ๊ฐ€๋Šฅ์„ฑ์ด ์กด์žฌํ•œ๋‹ค.

๐ŸŽƒ ๋‚˜์œ ์ฃผ์„โ€‹

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

๐ŸŽˆ ์ฃผ์ ˆ๊ฑฐ๋ฆฌ๋Š” ์ฃผ์„โ€‹

ํŠน๋ณ„ํ•œ ์ด์œ  ์—†์ด ์˜๋ฌด๊ฐ์œผ๋กœ ํ˜น์€ ํ”„๋กœ์„ธ์Šค์—์„œ ํ•˜๋ผ๊ณ  ํ•˜๋‹ˆ๊นŒ ๋งˆ์ง€๋ชปํ•ด ์ฃผ์„์„ ๋‹จ๋‹ค๋ฉด ์ „์ ์œผ๋กœ ์‹œ๊ฐ„๋‚ญ๋น„๋‹ค. ์ฃผ์„์„ ๋‹ฌ๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ๋‹ค๋ฉด ์ถฉ๋ถ„ํžˆ ์‹œ๊ฐ„์„ ๋“ค์—ฌ ์ตœ๊ณ ์˜ ์ฃผ์„์„ ๋‹ฌ๋„๋ก ๋…ธ๋ ฅํ•œ๋‹ค.

public void loadProperties() {
try {
String propertiesPath = propertiesLocation + "/" + PROPERTIES_FILE;
FileInputStream = new FileInputStream(propertiesPath);
loadedProperties.load(propertiesStream);
} catch(IOException e) {
// ์†์„ฑ ํŒŒ์ผ์ด ์—†๋‹ค๋ฉด ๊ธฐ๋ณธ๊ฐ’์„ ๋ชจ๋‘ ๋ฉ”๋ชจ๋ฆฌ๋กœ ์ฝ์–ด ๋“ค์˜€๋‹ค๋Š” ์˜๋ฏธ๋‹ค.
}
}

catch ๋ธ”๋ก์— ์žˆ๋Š” ์ฃผ์„์€ ๋ฌด์Šจ ๋œป์ผ๊นŒ? ํ™•์‹คํžˆ ์ €์ž์—๊ฒŒ์•ผ ์˜๋ฏธ๊ฐ€ ์žˆ๊ฒ ์ง€๋งŒ ๊ทธ ์˜๋ฏธ๊ฐ€ ๋‹ค๋ฅธ ์‚ฌ๋žŒ์—๊ฒŒ๋Š” ์ „ํ•ด์ง€์ง€ ์•Š๋Š”๋‹ค. ๋‹ต์„ ์•Œ์•„๋‚ด๋ ค๋ฉด ๋‹ค๋ฅธ ์ฝ”๋“œ๋ฅผ ๋’ค์ ธ๋ณด๋Š” ์ˆ˜๋ฐ–์— ์—†๋‹ค. ์ดํ•ด๊ฐ€ ์•ˆ ๋˜์–ด ๋‹ค๋ฅธ ๋ชจ์Šต๋“ค๊นŒ์ง€ ๋’ค์ ธ์•ผ ํ•˜๋Š” ์ฃผ์„์€ ๋…์ž์™€ ์ œ๋Œ€๋กœ ์†Œํ†ตํ•˜์ง€ ๋ชปํ•˜๋Š” ์ฃผ์„์ด๋‹ค. ๊ทธ๋Ÿฐ ์ฃผ์„์€ ๋ฐ”์ดํŠธ๋งŒ ๋‚ญ๋น„ํ•  ๋ฟ์ด๋‹ค.

๐ŸŽˆ ๊ฐ™์€ ์ด์•ผ๊ธฐ๋ฅผ ์ค‘๋ณตํ•˜๋Š” ์ฃผ์„โ€‹

์•„๋ž˜ ์˜ˆ์ œ๋Š” ๊ฐ„๋‹จํ•œ ํ•จ์ˆ˜๋กœ, ํ—ค๋”์— ๋‹ฌ๋ฆฐ ์ฃผ์„์ด ๊ฐ™์€ ์ฝ”๋“œ ๋‚ด์šฉ์„ ๊ทธ๋Œ€๋กœ ์ค‘๋ณตํ•œ๋‹ค. ์ž์นซํ•˜๋ฉด ์ฝ”๋“œ๋ณด๋‹ค ์ฃผ์„์„ ์ฝ๋Š” ์‹œ๊ฐ„์ด ๋” ์˜ค๋ž˜ ๊ฑธ๋ฆฐ๋‹ค.

// this.closed๊ฐ€ true์ผ ๋•Œ ๋ฐ˜ํ™˜๋˜๋Š” ์œ ํ‹ธ๋ฆฌํ‹ฐ ๋ฉ”์„œ๋“œ๋‹ค.
// ํƒ€์ž„์•„์›ƒ์— ๋„๋‹ฌํ•˜๋ฉด ์˜ˆ์™ธ๋ฅผ ๋˜์ง„๋‹ค.
public synchronized void waitForClose(final long timeoutMillis) throws Exception {
if (!closed) {
wait(timeoutMillis);
if (!closed) {
throw new Exception("MockResponseSender could not be closed");
}
}
}

์ฃผ์„์ด ์ฝ”๋“œ๋ณด๋‹ค ๋” ๋งŽ์€ ๋‚ด์šฉ์„ ์ œ๊ณตํ•˜์ง€ ๋ชปํ•œ๋‹ค. ์ฝ”๋“œ๋ฅผ ์ •๋‹นํ™”ํ•˜๋Š” ์ฃผ์„๋„ ์•„๋‹ˆ๊ณ , ์˜๋„๋‚˜ ๊ทผ๊ฑฐ๋ฅผ ์„ค๋ช…ํ•˜๋Š” ์ฃผ์„๋„ ์•„๋‹ˆ๋‹ค. ์ฝ”๋“œ๋ณด๋‹ค ์ฝ๊ธฐ๊ฐ€ ์‰ฝ์ง€๋„ ์•Š๋‹ค. ์‹ค์ œ๋กœ ์ฝ”๋“œ๋ณด๋‹ค ๋ถ€์ •ํ™•ํ•ด ๋…์ž๊ฐ€ ํ•จ์ˆ˜๋ฅผ ๋Œ€์ถฉ ์ดํ•ดํ•˜๊ณ  ๋„˜์–ด๊ฐ€๊ฒŒ ๋งŒ๋“ ๋‹ค.

๐ŸŽˆ ์˜คํ•ดํ•  ์—ฌ์ง€๊ฐ€ ์žˆ๋Š” ์ฃผ์„โ€‹

๋•Œ๋•Œ๋กœ ์˜๋„๋Š” ์ข‹์•˜์œผ๋‚˜ ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ๋”ฑ ๋งž์„ ์ •๋„๋กœ ์—„๋ฐ€ํ•˜๊ฒŒ๋Š” ์ฃผ์„์„ ๋‹ฌ์ง€ ๋ชปํ•˜๊ธฐ๋„ ํ•œ๋‹ค.

์œ„ ์˜ˆ์ œ์—์„œ this.closed๊ฐ€ true๋กœ ๋ณ€ํ•˜๋Š” ์ˆœ๊ฐ„์— ๋ฉ”์„œ๋“œ๋Š” ๋ฐ˜ํ™˜๋˜์ง€ ์•Š๋Š”๋‹ค. this.closed๊ฐ€ true์—ฌ์•ผ ๋ฉ”์„œ๋“œ๋Š” ๋ฐ˜ํ™˜๋œ๋‹ค. ์•„๋‹ˆ๋ฉด ๋ฌด์กฐ๊ฑด ํƒ€์ž„์•„์›ƒ์„ ๊ธฐ๋‹ค๋ ธ๋‹ค this.closed๊ฐ€ ๊ทธ๋ž˜๋„ true๊ฐ€ ์•„๋‹ˆ๋ฉด ์˜ˆ์™ธ๋ฅผ ๋˜์ง„๋‹ค.

๐ŸŽˆ ์˜๋ฌด์ ์œผ๋กœ ๋‹ค๋Š” ์ฃผ์„โ€‹

๋ชจ๋“  ํ•จ์ˆ˜์— Javadocs๋ฅผ ๋‹ฌ๊ฑฐ๋‚˜ ๋ชจ๋“  ๋ณ€์ˆ˜์— ์ฃผ์„์„ ๋‹ฌ์•„์•ผ ํ•œ๋‹ค๋Š” ๊ทœ์น™์€ ์–ด๋ฆฌ์„๊ธฐ ๊ทธ์ง€์—†๋‹ค. ์ด๋Ÿฐ ์ฃผ์„์€ ์ฝ”๋“œ๋ฅผ ๋ณต์žกํ•˜๊ฒŒ ๋งŒ๋“ค๋ฉฐ, ๊ฑฐ์ง“๋ง์„ ํผ๋œจ๋ฆฌ๊ณ , ํ˜ผ๋™๊ณผ ๋ฌด์งˆ์„œ๋ฅผ ์ดˆ๋ž˜ํ•œ๋‹ค.

์•„๋ž˜์™€ ๊ฐ™์€ ์ฃผ์„์€ ์•„๋ฌด ๊ฐ€์น˜๋„ ์—†๋‹ค. ์˜คํžˆ๋ ค ์ฝ”๋“œ๋งŒ ํ—ท๊ฐˆ๋ฆฌ๊ฒŒ ๋งŒ๋“ค๋ฉฐ, ๊ฑฐ์ง“๋งํ•  ๊ฐ€๋Šฅ์„ฑ์„ ๋†’์ด๋ฉฐ, ์ž˜๋ชป๋œ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•  ์—ฌ์ง€๋งŒ ๋งŒ๋“ ๋‹ค.

/**
*
* @param title CD ์ œ๋ชฉ
* @param author CD ์ €์ž
* @param tracks CD ํŠธ๋ž™ ์ˆซ์ž
* @param durationInMinutes CD ๊ธธ์ด(๋‹จ์œ„: ๋ถ„)
*/
public void addCD(String title, String author, int tracks, int durationInMinutes) {
CD cd = new CD();
cd.title = title;
cd.author = author;
cd.tracks = tracks;
cd.duration = durationInMinutes;
cdList.add(cd);
}

๐ŸŽˆ ์ด๋ ฅ์„ ๊ธฐ๋กํ•˜๋Š” ์ฃผ์„โ€‹

๋•Œ๋•Œ๋กœ ์‚ฌ๋žŒ๋“ค์€ ๋ชจ๋“ˆ์„ ํŽธ์ง‘ํ•  ๋•Œ๋งˆ๋‹ค ๋ชจ๋“ˆ ์ฒซ๋จธ๋ฆฌ์— ์ฃผ์„์„ ์ถ”๊ฐ€ํ•œ๋‹ค. ๊ทธ๋ฆฌํ•˜์—ฌ ๋ชจ๋“ˆ ์ฒซ ๋จธ๋ฆฌ ์ฃผ์„์€ ์ง€๊ธˆ๊นŒ์ง€ ๋ชจ๋“ˆ์— ๊ฐ€ํ•œ ๋ณ€๊ฒฝ์„ ๋ชจ๋‘ ๊ธฐ๋กํ•˜๋Š” ์ผ์ข…์˜ ์ผ์ง€ ํ˜น์€ ๋กœ๊ทธ๊ฐ€ ๋œ๋‹ค.

์˜ˆ์ „์—๋Š” ๋ชจ๋“  ๋ชจ๋“ˆ ์ฒซ๋จธ๋ฆฌ์— ๋ณ€๊ฒฝ ์ด๋ ฅ์„ ๊ธฐ๋กํ•˜๊ณ  ๊ด€๋ฆฌํ•˜๋Š” ๊ด€๋ก€๊ฐ€ ๋ฐ”๋žŒ์งํ–ˆ๋‹ค. ๋‹น์‹œ์—๋Š” ์†Œ์Šค ์ฝ”๋“œ ๊ด€๋ฆฌ ์‹œ์Šคํ…œ์ด ์—†์—ˆ์œผ๋‹ˆ๊นŒ. ํ•˜์ง€๋งŒ ์ด์ œ๋Š” ํ˜ผ๋ž€๋งŒ ๊ฐ€์ค‘ํ•  ๋ฟ์ด๋‹ค. ์™„์ „ํžˆ ์ œ๊ฑฐํ•˜๋Š” ํŽธ์ด ์ข‹๋‹ค.

๐ŸŽˆ ์žˆ์œผ๋‚˜ ๋งˆ๋‚˜ ํ•œ ์ฃผ์„โ€‹

๋•Œ๋•Œ๋กœ ์žˆ์œผ๋‚˜ ๋งˆ๋‚˜ ํ•œ ์ฃผ์„์„ ์ ‘ํ•œ๋‹ค. ์‰ฝ๊ฒŒ ๋งํ•ด, ๋„ˆ๋ฌด ๋‹น์—ฐํ•œ ์‚ฌ์‹ค์„ ์–ธ๊ธ‰ํ•˜๋ฉฐ ์ƒˆ๋กœ์šด ์ •๋ณด๋ฅผ ์ œ๊ณตํ•˜์ง€ ๋ชปํ•˜๋Š” ์ฃผ์„์ด๋‹ค.

/*
* ๊ธฐ๋ณธ ์ƒ์„ฑ์ž
*/
protected AnnualDateRule() {
// ...
}

๊ทธ๋ ‡๋‹จ ๋ง์ด์ง€? ๋‹ค์Œ์€ ์–ด๋–ค๊ฐ€?

/** ์›” ์ค‘ ์ผ์ž */
private int dayOfMonth;

์œ„์™€ ๊ฐ™์€ ์ฃผ์„์€ ์ง€๋‚˜์นœ ์ฐธ๊ฒฌ์ด๋ผ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ฃผ์„์„ ๋ฌด์‹œํ•˜๋Š” ์Šต๊ด€์— ๋น ์ง„๋‹ค. ์ฝ”๋“œ๋ฅผ ์ฝ์œผ๋ฉฐ ์ž๋™์œผ๋กœ ์ฃผ์„์„ ๊ฑด๋„ˆ๋›ด๋‹ค. ๊ฒฐ๊ตญ์€ ์ฝ”๋“œ๊ฐ€ ๋ฐ”๋€Œ๋ฉด์„œ ์ฃผ์„์€ ๊ฑฐ์ง“๋ง๋กœ ๋ณ€ํ•œ๋‹ค.

๐ŸŽˆ ๋ฌด์„œ์šด ์žก์Œโ€‹

๋–„๋กœ๋Š” Javadocs๋„ ์žก์Œ์ด๋‹ค. ๋‹ค์Œ์€ ์ž˜ ์•Œ๋ ค์ง„ ์˜คํ”ˆ ์†Œ์Šค ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ ๊ฐ€์ ธ์˜จ ์ฝ”๋“œ๋‹ค. ์•„๋ž˜ ๋‚˜์˜ค๋Š” Javadocs๋Š” ์–ด๋–ค ๋ชฉ์ ์„ ์ˆ˜ํ–‰ํ• ๊นŒ? ๋‹ต: ์—†๋‹ค. ๋‹จ์ง€ ๋ฌธ์„œ๋ฅผ ์ œ๊ณตํ•ด์•ผ ํ•œ๋‹ค๋Š” ์ž˜๋ชป๋œ ์š•์‹ฌ์œผ๋กœ ํƒ„์ƒํ•œ ์žก์Œ์ผ ๋ฟ์ด๋‹ค.

/** The name. */
private String name;
/** The version. */
private String version;

๐ŸŽˆ ํ•จ์ˆ˜๋‚˜ ๋ณ€์ˆ˜๋กœ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ์ฃผ์„์„ ๋‹ฌ์ง€ ๋งˆ๋ผโ€‹

๋‹ค์Œ ์ฝ”๋“œ๋ฅผ ์‚ดํŽด๋ณด์ž.

// ์ „์—ญ ๋ชฉ๋ก <smodule>์— ์†ํ•˜๋Š” ๋ชจ๋“ˆ์ด ์šฐ๋ฆฌ๊ฐ€ ์†ํ•œ ํ•˜์œ„ ์‹œ์Šคํ…œ์— ์˜์กดํ•˜๋Š”๊ฐ€?
if (smodule.getDependSubsystems().contains(subSysMod.getSubSystem()))

์ด ์ฝ”๋“œ์—์„œ ์ฃผ์„์„ ์—†์• ๊ณ  ๋‹ค์‹œ ํ‘œํ˜„ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

ArrayList moduleDependees = smodule.getDependSubsystems();
String ourSubSystem = subSysMod.getSubSystem();
if (moduleDependees.contains(ourSubSystem))

์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•œ ์ €์ž๋Š” (๊ฐ€๋Šฅ์„ฑ์ด์•ผ ํฌ๋ฐ•ํ•˜์ง€๋งŒ) ์ฃผ์„์„ ๋จผ์ € ๋‹ฌ๊ณ  ์ฃผ์„์— ๋งž์ถฐ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ–ˆ์„์ง€๋„ ๋ชจ๋ฅด๊ฒ ๋‹ค. ํ•˜์ง€๋งŒ ์œ„์™€ ๊ฐ™์ด ์ฃผ์„์ด ํ•„์š”ํ•˜์ง€ ์•Š๋„๋ก ์ฝ”๋“œ๋ฅผ ๊ฐœ์„ ํ•˜๋Š” ํŽธ์ด ๋” ์ข‹์•˜๋‹ค.

๐ŸŽˆ ์œ„์น˜๋ฅผ ํ‘œ์‹œํ•˜๋Š” ์ฃผ์„โ€‹

๋•Œ๋•Œ๋กœ ํ”„๋กœ๊ทธ๋ž˜๋จธ๋Š” ์†Œ์Šค ํŒŒ์ผ์—์„œ ํŠน์ • ์œ„์น˜๋ฅผ ํ‘œ์‹œํ•˜๋ ค ์ฃผ์„์„ ์‚ฌ์šฉํ•œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์ตœ๊ทผ์— ์‚ดํŽด๋ณด๋˜ ํ”„๋กœ๊ทธ๋žจ์—์„œ ๋‹ค์Œ ํ–‰์„ ๋ฐœ๊ฒฌํ–ˆ๋‹ค.

// Actions //////////////

๊ทนํžˆ ๋“œ๋ฌผ์ง€๋งŒ ์œ„์™€ ๊ฐ™์€ ๋ฐฐ๋„ˆ ์•„๋ž˜ ํŠน์ • ๊ธฐ๋Šฅ์„ ๋ชจ์•„๋†“์œผ๋ฉด ์œ ์šฉํ•œ ๊ฒฝ์šฐ๋„ ์žˆ๊ธด ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ์ผ๋ฐ˜์ ์œผ๋กœ ์œ„์™€ ๊ฐ™์€ ์ฃผ์„์€ ๊ฐ€๋…์„ฑ๋งŒ ๋‚ฎ์ถ”๋ฏ€๋กœ ์ œ๊ฑฐํ•ด์•ผ ๋งˆ๋•…ํ•˜๋‹ค. ํŠนํžˆ ๋’ท๋ถ€๋ถ„์— ์Šฌ๋ž˜์‹œ๋กœ ์ด์–ด์ง€๋Š” ์žก์Œ์€ ์ œ๊ฑฐํ•˜๋Š” ํŽธ์ด ์ข‹๋‹ค.

๋„ˆ๋ฌด ์ž์ฃผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ๋ฐฐ๋„ˆ๋Š” ๋ˆˆ์— ๋„๋ฉฐ ์ฃผ์˜๋ฅผ ํ™˜๊ธฐํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋ฏ€๋กœ ๋ฐ˜๋“œ์‹œ ํ•„์š”ํ•  ๋•Œ๋งŒ, ์•„์ฃผ ๋“œ๋ฌผ๊ฒŒ ์‚ฌ์šฉํ•˜๋Š” ํŽธ์ด ์ข‹๋‹ค. ๋ฐฐ๋„ˆ๋ฅผ ๋‚จ์šฉํ•˜๋ฉด ๋…์ž๊ฐ€ ํ”ํ•œ ์žก์Œ์œผ๋กœ ์—ฌ๊ฒจ ๋ฌด์‹œํ•œ๋‹ค.

๐ŸŽˆ ๋‹ซ๋Š” ๊ด„ํ˜ธ์— ๋‹ค๋Š” ์ฃผ์„โ€‹

๋•Œ๋กœ๋Š” ํ”„๋กœ๊ทธ๋ž˜๋จธ๋“ค์ด ๋‹ซ๋Š” ๊ด„ํ˜ธ์— ํŠน์ˆ˜ํ•œ ์ฃผ์„์„ ๋‹ฌ์•„๋†“๋Š”๋‹ค. ์ค‘์ฒฉ์ด ์‹ฌํ•˜๊ณ  ์žฅํ™ฉํ•œ ํ•จ์ˆ˜๋ผ๋ฉด ์˜๋ฏธ๊ฐ€ ์žˆ์„์ง€๋„ ๋ชจ๋ฅด์ง€๋งŒ ์ž‘๊ณ  ์บก์Šํ™”๋œ ํ•จ์ˆ˜๋Š” ์žก์Œ์ผ ๋ฟ์ด๋‹ค. ๊ทธ๋Ÿฌ๋ฏ€๋กœ ๋‹ซ๋Š” ๊ด„ํ˜ธ์— ์ฃผ์„์„ ๋‹ฌ์•„์•ผ๊ฒ ๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ ๋‹ค๋ฉด ๋Œ€์‹ ์— ํ•จ์ˆ˜๋ฅผ ์ค„์ด๋ ค ์‹œ๋„ํ•˜์ž.

public class wc {
public static void main(String[] args) {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String line;
int lineCount = 0;
int charCount = 0;
int wordCount = 0;
try {
while ((line = in.readLine()) != null) {
lineCount++;
charCount += line.length();
String words[] = line.split("\\W");
wordCount += words.length;
} // while

System.out.println("wordCount = " + wordCount);
System.out.println("lineCount = " + lineCount);
System.out.println("charCount = " + charCount);
} // try
catch (IOException e) {
System.err.println("Error: " + e.getMessage());
} // catch
} // main
}

๐ŸŽˆ ๊ณต๋กœ๋ฅผ ๋Œ๋ฆฌ๊ฑฐ๋‚˜ ์ €์ž๋ฅผ ํ‘œ์‹œํ•˜๋Š” ์ฃผ์„โ€‹

/* ๋ฝ์ด ์ถ”๊ฐ€ํ•จ */

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

๋‹ค์‹œ ํ•œ ๋ฒˆ ๊ฐ•์กฐํ•˜์ง€๋งŒ, ์œ„์™€ ๊ฐ™์€ ์ •๋ณด๋Š” ์†Œ์Šค ์ฝ”๋“œ ๊ด€๋ฆฌ ์‹œ์Šคํ…œ์— ์ €์žฅํ•˜๋Š” ํŽธ์ด ์ข‹๋‹ค.

๐ŸŽˆ ์ฃผ์„์œผ๋กœ ์ฒ˜๋ฆฌํ•œ ์ฝ”๋“œโ€‹

์ฃผ์„์œผ๋กœ ์ฒ˜๋ฆฌํ•œ ์ฝ”๋“œ๋งŒํผ ๋ฐ‰์‚ด์Šค๋Ÿฌ์šด ๊ด€ํ–‰๋„ ๋“œ๋ฌผ๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ฝ”๋“œ๋Š” ์ž‘์„ฑํ•˜์ง€ ๋งˆ๋ผ!

InputStreamResponse response = new InputStreamResponse();
response.setBody(formatter.getResultStream(), formatter.getByteCount());
// InputStream resultsStream = formatter.getResultStream();
// StreamReader reader = new StreamReader(resultsStream);
// response.setContent(reader.read(formatter.getByteCount()));

์ฃผ์„์œผ๋กœ ์ฒ˜๋ฆฌ๋œ ์ฝ”๋“œ๋Š” ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์ด ์ง€์šฐ๊ธฐ๋ฅผ ์ฃผ์ €ํ•œ๋‹ค. ์ด์œ ๊ฐ€ ์žˆ์–ด์„œ ๋‚จ๊ฒจ๋†“์•˜์œผ๋ฆฌ๋ผ๊ณ , ์ค‘์š”ํ•˜๋‹ˆ๊นŒ ์ง€์šฐ๋ฉด ์•ˆ ๋œ๋‹ค๊ณ  ์ƒ๊ฐํ•œ๋‹ค.

์†Œ์Šค ์ฝ”๋“œ ๊ด€๋ฆฌ ์‹œ์Šคํ…œ์ด ์šฐ๋ฆฌ๋ฅผ ๋Œ€์‹ ํ•ด ์ฝ”๋“œ๋ฅผ ๊ธฐ์–ตํ•ด์ค€๋‹ค. ์ด์ œ ์ฃผ์„์œผ๋กœ ์ฒ˜๋ฆฌํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค. ๊ทธ๋ƒฅ ์ฝ”๋“œ๋ฅผ ์‚ญ์ œํ•˜๋ผ. ์žƒ์–ด๋ฒ„๋ฆด ์—ผ๋ ค๋Š” ์—†๋‹ค. ์•ฝ์†ํ•œ๋‹ค.

๐ŸŽˆ HTML ์ฃผ์„โ€‹

์†Œ์Šค ์ฝ”๋“œ์—์„œ HTML ์ฃผ์„์€ ํ˜์˜ค ๊ทธ ์ž์ฒด๋‹ค. HTML ์ฃผ์„์€ ํŽธ์ง‘๊ธฐ/IDE์—์„œ์กฐ์ฐจ ์ฝ๊ธฐ๊ฐ€ ์–ด๋ ต๋‹ค. ๋„๊ตฌ๋กœ ์ฃผ์„์„ ๋ฝ‘์•„ ์›น ํŽ˜์ด์ง€์— ์˜ฌ๋ฆด ์ž‘์ •์ด๋ผ๋ฉด ์ฃผ์„์— HTML ํƒœ๊ทธ๋ฅผ ์‚ฝ์ž…ํ•ด์•ผ ํ•˜๋Š” ์ฑ…์ž„์€ ํ”„๋กœ๊ทธ๋ž˜๋จธ๊ฐ€ ์•„๋‹ˆ๋ผ ๋„๊ตฌ๊ฐ€ ์ ธ์•ผํ•œ๋‹ค.

๐ŸŽˆ ์ „์—ญ ์ •๋ณดโ€‹

์ฃผ์„์„ ๋‹ฌ์•„์•ผ ํ•œ๋‹ค๋ฉด ๊ทผ์ฒ˜์— ์žˆ๋Š” ์ฝ”๋“œ๋งŒ ๊ธฐ์ˆ ํ•˜๋ผ. ์ฝ”๋“œ ์ผ๋ถ€์— ์ฃผ์„์„ ๋‹ฌ๋ฉด์„œ ์‹œ์Šคํ…œ์˜ ์ „๋ฐ˜์ ์ธ ์ •๋ณด๋ฅผ ๊ธฐ์ˆ ํ•˜์ง€ ๋งˆ๋ผ.

/**
* ์ ํ•ฉ์„ฑ ํ…Œ์ŠคํŠธ๊ฐ€ ๋™์ž‘ํ•˜๋Š” ํฌํŠธ: ๊ธฐ๋ณธ๊ฐ’์€ <b>8082</b>
*
* @param fitnessePort
*/
public void setFitnessePort(int fitnessePort) {
this.fitnessePort = fitnessePort;
}

๐ŸŽˆ ๋„ˆ๋ฌด ๋งŽ์€ ์ •๋ณดโ€‹

์ฃผ์„์—๋‹ค ํฅ๋ฏธ๋กœ์šด ์—ญ์‚ฌ๋‚˜ ๊ด€๋ จ ์—†๋Š” ์ •๋ณด๋ฅผ ์žฅํ™ฉํ•˜๊ฒŒ ๋Š˜์—ฌ๋†“์ง€ ๋งˆ๋ผ.

๐ŸŽˆ ๋ชจํ˜ธํ•œ ๊ด€๊ณ„โ€‹

์ฃผ์„๊ณผ ์ฃผ์„์ด ์„ค๋ช…ํ•˜๋Š” ์ฝ”๋“œ๋Š” ๋‘˜ ์‚ฌ์ด ๊ด€๊ณ„๊ฐ€ ๋ช…๋ฐฑํ•ด์•ผ ํ•œ๋‹ค. ์ด์™• ๊ณค๋“ฑ๋ ค ์ฃผ์„์„ ๋‹ฌ์•˜๋‹ค๋ฉด ์ ์–ด๋„ ๋…์ž๊ฐ€ ์ฃผ์„๊ณผ ์ฝ”๋“œ๋ฅผ ์ฝ์–ด๋ณด๊ณ  ๋ฌด์Šจ ์†Œ๋ฆฐ์ง€ ์•Œ์•„์•ผ ํ•˜์ง€ ์•Š๊ฒ ๋Š”๊ฐ€?

/*
* ๋ชจ๋“  ํ”ฝ์…€์„ ๋‹ด์„ ๋งŒํผ ์ถฉ๋ถ„ํ•œ ๋ฐฐ์—ด๋กœ ์‹œ์ž‘ํ•œ๋‹ค(์—ฌ๊ธฐ์— ํ•„ํ„ฐ ๋ฐ”์ดํŠธ๋ฅผ ๋”ํ•œ๋‹ค).
* ๊ทธ๋ฆฌ๊ณ  ํ—ค๋” ์ •๋ณด๋ฅผ ์œ„ํ•ด 200๋ฐ”์ดํŠธ๋ฅผ ๋”ํ•œ๋‹ค.
*/
this.pngBytes = new byte[((this.width + 1) * this.height * 3) + 200];

์—ฌ๊ธฐ์„œ ํ•„ํ„ฐ ํŒŒ์ดํŠธ๋ž€ ๋ฌด์—‡์ผ๊นŒ? +1๊ณผ ๊ด€๋ จ์ด ์žˆ์„๊นŒ? ์•„๋‹ˆ๋ฉด *3๊ณผ ๊ด€๋ จ์ด ์žˆ์„๊นŒ? ์•„๋‹ˆ๋ฉด ๋‘˜ ๋‹ค? ํ•œ ํ”ฝ์…€์ด ํ•œ ๋ฐ”์ดํŠธ์ธ๊ฐ€? 200์„ ์ถ”๊ฐ€ํ•˜๋Š” ์ด์œ ๋Š”? ์ฃผ์„์„ ๋‹ค๋Š” ๋ชฉ์ ์€ ์ฝ”๋“œ๋งŒ์œผ๋กœ ์„ค๋ช…์ด ๋ถ€์กฑํ•ด์„œ๋‹ค. ์ฃผ์„ ์ž์ฒด๊ฐ€ ๋‹ค์‹œ ์„ค๋ช…์„ ์š”๊ตฌํ•˜๋‹ˆ ์•ˆํƒ€๊น๊ธฐ ๊ทธ์ง€์—†๋‹ค.

๐ŸŽˆ ํ•จ์ˆ˜ ํ—ค๋”โ€‹

์งง์€ ํ•จ์ˆ˜๋Š” ๊ธด ์„ค๋ช…์ด ํ•„์š” ์—†๋‹ค. ์งง๊ณ  ํ•œ ๊ฐ€์ง€๋งŒ ์ˆ˜ํ–‰ํ•˜๋ฉฐ ์ด๋ฆ„์„ ์ž˜ ๋ถ™์ธ ํ•จ์ˆ˜๊ฐ€ ์ฃผ์„์œผ๋กœ ํ—ค๋”๋ฅผ ์ถ”๊ฐ€ํ•œ ํ•จ์ˆ˜๋ณด๋‹ค ํ›จ์”ฌ ์ข‹๋‹ค.

๐ŸŽˆ ๋น„๊ณต๊ฐœ ์ฝ”๋“œ์—์„œ Javadocsโ€‹

๊ณต๊ฐœ API๋Š” Javadocs๊ฐ€ ์œ ์šฉํ•˜์ง€๋งŒ ๊ณต๊ฐœํ•˜์ง€ ์•Š์„ ์ฝ”๋“œ๋ผ๋ฉด Javadocs๋Š” ์“ธ๋ชจ๊ฐ€ ์—†๋‹ค. ์‹œ์Šคํ…œ ๋‚ด๋ถ€์— ์†ํ•œ ํด๋ž˜์Šค์™€ ํ•จ์ˆ˜์— Javadocs๋ฅผ ์ƒ์„ฑํ•  ํ•„์š”๋Š” ์—†๋‹ค. ์œ ์šฉํ•˜์ง€ ์•Š์„ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ Javadocs ์ฃผ์„์ด ์š”๊ตฌํ•˜๋Š” ํ˜•์‹์œผ๋กœ ์ธํ•ด ์ฝ”๋“œ๋งŒ ๋ณด๊ธฐ ์‹ซ๊ณ  ์‚ฐ๋งŒํ•ด์งˆ ๋ฟ์ด๋‹ค.