[ Programming > Clean Code ]
[ํด๋ฆฐ ์ฝ๋] 4-5์ฅ ์ฃผ์-ํ์ ๋ง์ถ๊ธฐ
ํด๋ฆฐ ์ฝ๋
์ด๋ฒ ๊ธ์์๋ ์ข์ ์ฃผ์ ์ฐ๋ ๋ฐฉ๋ฒ๊ณผ, ํ์ ๋ง์ถ๊ธฐ ๋ฐฉ๋ฒ ๋ค์ ๋ํด์ ์๊ฐํ ๊ฒ์.
4์ฅ. ์ฃผ์
์ ๋ฌ์ง ์ฃผ์์ ๊ทธ ์ด๋ค ์ ๋ณด๋ณด๋ค ์ ์ฉํด์. ํ์ง๋ง ๊ทผ๊ฑฐ ์๋ ์ฃผ์์ ์ฝ๋๋ฅผ ์ดํดํ๊ธฐ ์ด๋ ต๊ฒ ๋ง๋ค์ด์. ๊ทธ๋ฆฌ๊ณ ์ค๋ ๊ด๋ฆฌ๊ฐ ์๋ ์ฃผ์์ ์๋ชป๋ ์ ๋ณด๋ฅผ ์ ๋ฌํ๊ธฐ๋ ํด์.
์ ์๋ ์ฃผ์์ ํ์์ ์ด๋ผ ํํํด์. ์ฝ๋ ์์ฒด์ ํํ๋ ฅ๊ณผ ์ ๋ฌ๋ ฅ์ด ์๋ค๋ฉด ์ฃผ์์ ๊ฑฐ์ ํ์ํ์ง ์๊ธฐ ๋๋ฌธ์ด์์. ์ฆ, ๋์ ์ฝ๋์ ์ฃผ์์ ๋ฌ์ ๊ฒฝ์ฐ๋ผ๊ณ ๋ณผ ์ ์์ด์. ๊ทธ๋์ ์ฃผ์์ ๋ฌ๊ธฐ์ ์ ๋จผ์ ์ฝ๋๋ก ์๋๋ฅผ ํํํ ๋ฐฉ๋ฒ์ด ์์์ง ์๊ฐํด๋ณด๋ ๊ฒ์ด ์ข์์. ์ฃผ์์ ๋ฌ๋ฉด ๋ณธ์ธ์ด ํํ๋ ฅ์ด ๋ถ์กฑํจ์ ์ธ์ ํ๋ ๊ฒ๊ณผ ๋ง์ฐฌ๊ฐ์ง์์.
๊ทธ๋ฌ๋ฉด ์์ด๋ ๊ฒ ์ฃผ์์ ๋ฏธ์ํ ๊น์? ๋ฐ๋ก ์ฃผ์์ด ๊ฑฐ์ง๋งํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์์์์. ๊ณ ์์ ์ผ๋ก ๊ฑฐ์ง๋งํ๋ ๊ฒ์ ์๋์ง๋ง, ์ฃผ์์ด ์ค๋๋ ์๋ก ์ฝ๋์์ ๋ฉ์ด์ง๊ธฐ ๋๋ฌธ์ด์์. ๋ํ ๊ฐ๋ฐ์๊ฐ ์ฃผ์์ ์ ์ง ๋ฐ ๋ณด์ํ๋ ๊ฒ๋ ํ์ค์ ์ผ๋ก ๋ถ๊ฐ๋ฅํ๋ค๊ณ ์ฌ๊ฒจ์ ธ์. ์๋ง๋ ์ฃผ์์ ๋ฌ์๋ดค์ผ๋ฉด ์๊ฑฐ์์. ์ธ์ ์ผ๋์ง ๊ธฐ์ต์ด ์๋์.
์ฝ๋๋ ๋ณํํ๊ณ ์งํํด์. ์ฌ๊ธฐ ์ ๊ธฐ ์ฎ๊ฒจ๋ค๋๊ธฐ๋ ํด์. ๊ทธ๋ฆฌ๊ณ ๋ถ์ดํ๋ค๊ฐ ํฉ์ณ์ง๊ธฐ๋ ํฉ๋๋ค. ๊ทธ๋์ ์ฃผ์์ด ์ฝ๋๋ฅผ ๋ฐ๋ผ๊ฐ๊ธฐ ํ๋ค์ด์.
์ฃผ์์ ๋์ ์ฝ๋๋ฅผ ๋ณด์ํ์ง ๋ชปํ๋ค.
์ฝ๋์ ์ฃผ์์ ์ถ๊ฐํ๋ ๊ฐ์ฅ ์ผ๋ฐ์ ์ธ ์ด์ ๋ ์ฝ๋ ํ์ง์ด ๋์๊ธฐ ๋๋ฌธ์ด์์. ๋ชจ๋์ ์ง๊ณ ๋ณด๋ ์ง์์๊ฐ ์๋ง์ด๊ณ ์์๋จน๊ธฐ๊ฐ ํ๋ค์ด ์ฃผ์์ ๋ฌ์์ผ๊ฒ ๋ค๋ ๊ฒฐ์ฌ์ ํ์ฃ . ์ด๋ด ๋ "์ฃผ์์ ๋ฌ์์ผ๊ฒ ๋ค!"๊ฐ ์๋๋ผ "์ฝ๋๋ฅผ ์ ๋ฆฌํด์ผ๊ฒ ๋ค!"๋ผ๊ณ ๋งํ ์ ์์ด์ผํด์.
ํํ๋ ฅ์ด ํ๋ถํ๊ณ ๊น๋ํ๋ฉฐ ์ฃผ์์ด ๊ฑฐ์ ์๋ ์ฝ๋๊ฐ ๋ณต์กํ๊ณ ์ด์์ ํ๋ฉฐ ์ฃผ์์ด ๋ง์ด ๋ฌ๋ฆฐ ์ฝ๋๋ณด๋ค ์ข์์
์ฝ๋๋ก ์๋๋ฅผ ํํํ๋ผ!
ํ์คํ ์ฝ๋๋ง์ผ๋ก ์๋๋ฅผ ์ค๋ช ํ๊ธฐ ์ด๋ ค์ด ๊ฒฝ์ฐ๊ฐ ์์ด์. ํ์ง๋ง ๋ง์ ๊ฐ๋ฐ์๊ฐ ์ด๋ฅผ ์ฝ๋๋ ํ๋ฅญํ ์๋จ์ด ์๋๋ผ๊ณ ์๋ชป ์๊ฐํด์. ๋ค์ ์์ ๋ก ์์๋ด์.
1๋ฒ ์์ // ์ง์์๊ฒ ๋ณต์ง ํํ์ ๋ฐ์ ์๊ฒฉ์ด ์๋์ง ๊ฒ์ฌํ๋ค.if((employee.flags & HOURLY_FLAG) && (employee.age > 5))2๋ฒ ์์ if(employee.isEligibleForFullBenefits())๋ ์์ ๋ฅผ ๋ณด๋ฉด ์ด๋ค๊ฐ์? ๋ช ์ด๋ง ๋ ์๊ฐํ๋ฉด ์ฝ๋๋ก ๋๋ค์ ์๋๋ฅผ ํํํ ์ ์์์ ์ ์ ์์ด์. ์ฃผ์์ผ๋ก ๋ฌ๋ ค๋ ์ค๋ช ์ ํจ์๋ก ๋ง๋ค์ด ํํํ๋ฉด ์ข์์.
์ข์ ์ฃผ์
์ ๋ง ์ข์ ์ฃผ์์, ์ฃผ์์ ๋ฌ์ง ์์ ๋ฐฉ๋ฒ์ ์ฐพ์๋ธ ์ฃผ์์ด์์. ์ฌ๊ธฐ์๋ ์ ์ตํ๊ฑฐ๋ ํ์ํ ์ฃผ์์ ์๊ฐํ๋ ค๊ณ ํด์.
๋ฒ์ ์ธ ์ฃผ์
ํ์ฌ๊ฐ ์ ๋ฆฝํ ๊ตฌํ ํ์ค์ ๋ง์ถฐ ๋ฒ์ ์ธ ์ด์ ๋ก ํน์ ์ฃผ์์ ๋ฃ์ ์ ์์ด์. ๋ํ์ ์ธ ์๋ก ์์ค ํ์ผ ์ฒซ๋จธ๋ฆฌ์ ๋ค์ด๊ฐ๋ ์ ์๊ถ ์ ๋ณด์ ์์ ๊ถ ์ ๋ณด์์.
// Copyright (C) 2023,2024,2025 by Object Mentor, Inc. All rights reserved.// GNU General Public License ๋ฒ์ 2 ์ด์์ ๋ฐ๋ฅด๋ ์กฐ๊ฑด์ผ๋ก ๋ฐฐํฌํ๋ค.์ ๋ณด๋ฅผ ์ ๊ณตํ๋ ์ฃผ์
๊ธฐ๋ณธ์ ์ธ ์ ๋ณด๋ฅผ ์ฃผ์์ผ๋ก ์ ๊ณตํ๋ฉด ํธ๋ฆฌํ๊ธฐ๋ํด์. ์๋ฅผ ๋ค์ด ๋ค์๊ณผ ๊ฐ์ ์ฃผ์์ด์์.
// ํ
์คํธ ์ค์ธ Responder ์ธ์คํด์ค๋ฅผ ๋ฐํํ๋ค.protected abstract Responder responderInstance();=> ๊ฐ์ , responderBeingTested๋ก ์ด๋ฆ ๋ฐ๊พธ๋ฉด ์ฃผ์์ด ํ์ ์์ด์ง.๋ฌผ๋ก ์ ์ฃผ์๋ ์ข์ง๋ง ๋ค์๊ณผ ๊ฐ์ ์์๊ฐ ๋ ์ข์ ์์์์.
// kk:mm:ss EEE, MMM dd, yyyy ํ์์ด๋ค.Pattern timeMatcher = Pattern.compie( "\\d*:\\d*:\\d* \\w*, \\w* \\d*, \\d*");์์ ์ ์ํ ์ฃผ์์ ์ฝ๋์์ ์ฌ์ฉํ ์ ๊ทํํ์์ด ์๊ฐ๊ณผ ๋ ์ง๋ฅผ ๋ปํ๋ค๊ณ ์ค๋ช ํด์. ์ด์์ด๋ฉด ์๊ฐ๊ณผ ๋ ์ง๋ฅผ ๋ณํํ๋ ํด๋์ค๋ฅผ ๋ง๋ค์ด ์ฝ๋๋ฅผ ์ฎ๊ฒจ์ฃผ๋ฉด ๋ ์ข๊ณ ๊น๋ํด์. ๊ทธ๋ฌ๋ฉด ์ฃผ์์ด ํ์์์ด์ง๋๊น์.
์๋๋ฅผ ์ค๋ช ํ๋ ์ฃผ์
๋๋๋ก ์ฃผ์์ ๊ตฌํ์ ์ดํดํ๊ฒ ๋์์ฃผ๋ ๊ฒ์ ๋์ด ๊ฒฐ์ ์ ๊น๋ฆฐ ์๋๊น์ง ์ค๋ช ํด์. ๋ค์ ์์ ๋ก ๋ด์.
public int compareTo(Object o) { if(o instanceof WikiPagePath) { WikiPagePath p = (WikiPagePath) o; String compressedName = StringUtil.join(names, ""); String compressedArgumentName = StringUtil.join(p.name, ""); String CompressedName.compareTo(compressedArgumentName); } return 1; // ์ค๋ฅธ์ชฝ ์ ํ์ด๋ฏ๋ก ์ ๋ ฌ ์์๊ฐ ๋ ๋๋ค.}๋ค์ ์์ ๊ฐ ๋ ์ข์ ์์ ์์. ์ ์๊ฐ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ๋ฐฉ์์ ๋์ํ์ง ์๋๋ผ๋ ์ ์์ ์๋๊ฐ ๋ช ํํ ๋๋ฌ๋์.
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"); WikiPagePath ab = PathParser.parse("PageA.PageB"); WikiPagePath b = PathParser.parse("PageB"); WikiPagePath aa = PathParser.parse("PageA.PageA"); WikiPagePath bb = PathParser.parse("PageB.PageB"); WikiPagePath ba = PathParser.parse("PageB.PageB"); assertTrue(a.compareTo(a) == 0); // a == a assertTrue(a.compareTo(b) != 0); // a != b assertTrue(ab.compareTo(ab) == 0); // ab == ab assertTrue(a.compareTo(b) == -1); // a < a assertTrue(aa.compareTo(ab) == -1); // aa < ab assertTrue(ba.compareTo(bb) == -1); // ba < bb assertTrue(b.compareTo(a) == 1); // b > a assertTrue(ab.compareTo(aa) == 1); // ab > aa assertTrue(bb.compareTo(ba) == 1); // bb > ba}์ ์ฝ๋๋ ์๋ชป๋ ์ฃผ์์ ์ ์ ํ๋ฅ ์ด ๋์์. ๊ทธ๋ฆฌ๊ณ ์ณ๋ฐ๋ฅธ์ง ๊ฒ์ฆํ๊ธฐ๋ ํ๋ค๊ณ ์. ์ด๊ฒ์ด ์๋ฏธ๋ฅผ ๋ช ํํํ๋ ์ฃผ์์ด ํ์ํ ์ด์ ์ธ ๋์์ ์ฃผ์์ด ์ํํ ์ด์ ์์.
๊ฒฐ๊ณผ๋ฅผ ๊ฒฝ๊ณ ํ๋ ์ฃผ์
๋๋ก ๋ค๋ฅธ ํ๋ก๊ทธ๋๋จธ์๊ฒ ๊ฒฐ๊ณผ๋ฅผ ๊ฒฝ๊ณ ํ ๋ชฉ์ ์ผ๋ก ์ฃผ์์ ์ฌ์ฉํด์. ์๋ฅผ ๋ค๋ฉด ๋ค์์ ํน์ ํ ์คํธ ์ผ์ด์ค๋ฅผ ๊บผ์ผํ๋ ์ด์ ๋ฅผ ์ค๋ช ํ๋ ์ฃผ์์ด์์.
// ์ฌ์ ์๊ฐ์ด ์์ผ๋ฉด ์คํํ์ง ๋ง์ธ์.public void _testWithReallyBigFile(){ writeLineToFile(10000000); response.setBody(testFile); response.readyToSend(this); String responseString = output.toString(); assertSubString("Content-Length: 1000000000", respnseString); assertTrue(bytesSent > 1000000000);}์ด๋ฒ์๋ ๋ค๋ฅธ ์ ์ ํ ์ฃผ์์ ๋ณด์ฌ์ค๊ฒ์.
public static SimpleDateFormat makeStandardHttpDateFormat(){ // SimpleDateFormat์ ์ค๋ ๋์ ์์ ํ์ง ์์ต๋๋ค. // ๋ฐ๋ผ์ ๊ฐ ์ธ์คํด์ค๋ฅผ ๋
๋ฆฝ์ ์ผ๋ก ์์ฑํด์ผ ํฉ๋๋ค. SimpleDateFormat df = new SimpleDateformat("EEE, dd MMM yyyy HH:mm:ss z"); df.setTimeZone(TimeZone.getTimeZone("GMT")); return df;}๋ ๋์ ํด๊ฒฐ์ฑ ์ด ์๋ค๊ณ ๋งํ๋ ์ฌ๋๋ ์์๊ฑฐ์์. ๊ทธ๋ผ์๋ ์ด ์ฃผ์์ ํฉ๋ฆฌ์ ์ด์์. ํจ์จ์ ์ํด ์ ์ ์ด๊ธฐํ ํจ์๋ฅผ ์ฌ์ฉํ๋ ค๋ ํ๋ก๊ทธ๋๋จธ๊ฐ ์ฃผ์ ๋๋ฌธ์ ์ค์๋ฅผ ํผํ ์ ์์ด์.
TODO ์ฃผ์
๋๋ก๋ "์์ผ๋ก ํ ์ผ"์ TODO ์ฃผ์์ผ๋ก ๋จ๊ฒจ๋๋ฉด ํธํด์. ๋ค์์ ํจ์๋ฅผ ๊ตฌํํ์ง ์์ ์ด์ ์ ๋ฏธ๋ ๋ชจ์ต์ TODO ์ฃผ์์ผ๋ก ์ค๋ช ํ ์์ ์์.
// TODO-MdM ํ์ฌ ํ์ํ์ง ์๋ค.// ์ฒดํฌ์์ ๋ชจ๋ธ์ ๋์
ํ๋ฉด ํจ์๊ฐ ํ์ ์๋ค.protected VersionInfo makeVersion() throws Exception { return null}TODO ์ฃผ์์ ํ๋ก๊ทธ๋๋จธ๊ฐ ํ์ํ๋ค ์ฌ๊ธฐ์ง๋ง ๋น์ฅ ๊ตฌํํ๊ธฐ ์ด๋ ค์ด ์ ๋ฌด๋ฅผ ๊ธฐ์ ํด์. ๋ ์ด์ ํ์ ์๋ ๊ธฐ๋ฅ์ ์ญ์ ํ๋ผ๋ ์๋ฆผ, ๋๊ตฐ๊ฐ์๊ฒ ๋ฌธ์ ๋ฅผ ๋ด๋ฌ๋ผ๋ ์์ฒญ, ๋ ์ข์ ์ด๋ฆ์ ๋ ์ฌ๋ ค๋ฌ๋ผ๋ ๋ถํ, ์์ผ๋ก ๋ฐ์ํ ์ด๋ฒคํธ์ ๋ง์ถฐ ์ฝ๋๋ฅผ ๊ณ ์น๋ผ๋ ์ฃผ์ ๋ฑ์ ์ ์ฉํด์. ํ์ง๋ง ์ด๋ค ์๋๋ก ์ฌ์ฉํด๋, ๋์ ์ฝ๋๋ฅผ ๋จ๊ฒจ๋๋ ํ๊ณ๊ฐ ๋๋ฉด ์๋ผ์.
์์ฃผ์ฌ์ฉ๋๋ TODO ๊ฐ์ ์ฃผ์ ํ๊ทธ์ ๋ํด์ ์ ๋ฆฌํด๋ดค์ด์.
TODO : ๋น์ฅ์ ์ด๋ ต์ง๋ง ๋์ค์ ์ถ๊ฐ๋ก ์์ ํด์ผ ํ๋ ๋ถ๋ถ ํํ
FIXME : ์ฆ์ ์์ ์ด ํ์ํ ๋๋์์ ์ด ํ์ํ๋ค๊ณ ๋ ผ์ํ ์ฝ๋๋ฅผ ํํ
HACK : ์์์ ์ธ ํด๊ฒฐ์ฑ (๋ฌธ์ ํํผ ๊ธฐ๋ฒ)์ ๋ํ ์ฃผ์
XXX : ๋ค๋ฅธ ํ๋ก๊ทธ๋๋จธ์๊ฒ ๋์ค์ ๊ฒํ ํ๊ฑฐ๋ ๊ฐ์ ํ ํ์๊ฐ ์๋ ๋ถ๋ถ(๋นํจ์จ์ ์ธ ์ฝ๋) ํํ
์ค์์ฑ์ ๊ฐ์กฐํ๋ ์ฃผ์
๋์๋กญ์ง ์๋ค๊ณ ์ฌ๊ฒจ์ง ๊ฒ์ ์ค์์ฑ์ ๊ฐ์กฐํ๊ธฐ ์ํด ์ฌ์ฉํด๋ ์ข์์.
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๊ฐ ์ข์ ์์์. ๊ณต๊ฐ API๋ฅผ ๊ตฌํํ๋ค๋ฉด ๋ฐ๋์ ํ๋ฅญํ Javadocs๋ฅผ ์์ฑํด์ผํด์. ๋ค๋ฅธ ์ฃผ์๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก ๊ทธ๋ฆ๋ ์ ๋ณด๋ฅผ ์ ๋ฌํ์ง ์๋๋ก ํด์ผํด์.
๋์ ์ฃผ์
๋๋ค์ ์ฃผ์์ด ๋์ ์ฃผ์์ ์ํด์. ํ์ ํ ์ฝ๋๋ฅผ ๋ณด์กฐํ๊ฑฐ๋, ๋ณ๋ช ํ๊ฑฐ๋, ํฉ๋ฆฌํํ๋ ๋ฑ ํ๋ก๊ทธ๋๋จธ๊ฐ ์ฃผ์ ๊ฑฐ๋ฆฌ๋ ๋ ๋ฐฑ์ ์ง๋์ง์์์.
์ฃผ์ ๊ฑฐ๋ฆฌ๋ ์ฃผ์
์ด์ ์์ด ์๋ฌด๊ฐ์ ํน์ ํ๋ก์ธ์ค ์๋์ ์ฃผ์์ ๋ฌ๋ฉด ์๊ฐ ๋ญ๋น์์. ์ฃผ์์ ๋ฌ๊ธฐ๋ก ๊ฒฐ์ ํ๋ค๋ฉด, ์๊ฐ์ ๋ค์ฌ ์ต๊ณ ์ ์ฃผ์์ ๋ฌ๋๋ก ๋ ธ๋ ฅํด์ผํด์. ๋ค์ ์์๋ ๊ทธ๋ฅ ์ฃผ์ ๊ฑฐ๋ ค ํ๋ ์ด ๋ถ๊ฐ๋ฅํ ์ฃผ์์ด์์.
public void loadProperties() { try { String propertiesPath = propertiesLocation + "/" + PROPERTIES_FILE; FileInputStream propertiesStream = new FileInputStream(propertiesPath); loadedProperties.load(propertiesStream); } catch(IOException e) { // ์์ฑ ํ์ผ์ด ์๋ค๋ฉด ๊ธฐ๋ณธ๊ฐ์ ๋ชจ๋ ๋ฉ๋ชจ๋ฆฌ๋ก ์ฝ์ด ๋ค์๋ค๋ ์๋ฏธ๋ค }}catch ๋ธ๋ก์ ์๋ ์ฃผ์ ์๋ฏธ๊ฐ ์ ํ ์ ํด์ง์ง ์์์. IOException์ด ๋ฐ์ํ๋ฉด ์์ฑ ํ์ผ์ด ์๋ค๋ ๋ป์ธ๊ฑฐ ๊ฐ์์. ๊ทธ๋ฐ๋ฐ ๊ธฐ๋ณธ๊ฐ์ ๋ ๋ญ์ง ์๋ฌด๊ฒ๋ ๋ชจ๋ฅด๊ฒ ์ด์. ๋ต์ ์์๋ด๋ ค๋ฉด ๋ค๋ฅธ ์ฝ๋๋ฅผ ๋ค์ ธ๋ณด๋ ์๋ฐ์ ์๊ฒ ๋ค์.
๊ฐ์ ์ด์ผ๊ธฐ๋ฅผ ์ค๋ณตํ๋ ์ฃผ์
์๋ ์์๋ ์ฃผ์์ด ์ฝ๋์ ๋ด์ฉ์ ๊ทธ๋๋ก ์ ์์ด์. ์์นซํ๋ฉด ์ฝ๋๋ณด๋ค ์ฃผ์ ์ฝ๋ ์๊ฐ์ด ๋ ๊ฑธ๋ฆฌ๊ฒ ๋ค์.
// 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"); } } }}์ ์ฝ๋์ ๋ฌธ์ ๋ ์ฝ๋๊ฐ ๋ถ์ ํํด ์๋ฏธ๋ฅผ ๋ชจ๋ ์ ๋ฌํ์ง ๋ชปํ๊ธฐ ๋๋ฌธ์ ์ฃผ์์ ์ผ์ ํ๋ฅ ์ด ๋์์. ์ฃผ์์ ๋ณด๊ณ ๋์ถฉ ๋์ด๊ฐ์ฃผ๊ธธ ๋ฐ๋ผ๋ ๋๋์ด์์.
๋ ๋ค๋ฅธ ์์๋ก Tomcat์์ ๊ฐ์ ธ์จ ์ฝ๋์์. ์ธ๋ชจ์๋ ์ค๋ณต๋ Javadocs๊ฐ ๋๋ฌด ๋ง์์.
public abstract class ContainerBase implements Container, Lifecycle, Pipeline, MBeanRegistration, Serializable { /** * ์ด ์ปดํฌ๋ํธ์ ํ๋ก์ธ์ ์ง์ฐ๊ฐ */ protected int backgroundProcessorDelay = -1; /** * ์ด ์ปดํฌ๋ํธ๋ฅผ ์ง์ํ๊ธฐ ์ํ ์๋ช
์ฃผ๊ธฐ ์ด๋ฒคํธ */ protected LifecycleSupport lifecycle = new LifecycleSupport(this); /** * ์ด ์ปดํฌ๋ํธ๋ฅผ ์ํ ์ปจํ
์ด๋ ์ด๋ฒคํธ ๋ฆฌ์ค๋ */ protected ArrayList listeners = new ArrayList(); /** * ์ปจํ
์ด๋์ ๊ด๋ จ๋ loader ๊ตฌํ */ protected Loader loader = null; /** * ์ปจํ
์ด๋์ ๊ด๋ จ๋ Logger ๊ตฌํ */ protected Log logger = null; /** * ๊ด๋ จ logger ์ด๋ฆ */ protected String logName = null; /** * ์ปจํ
์ด๋์ ๊ด๋ จ๋ Manager ๊ตฌํ */ protected Manager manager = null; /** * ์ปจํ
์ด๋์ ๊ด๋ จ๋ Cluster */ protected Cluster cluster = null; /** * ์ฌ๋์ด ์ฝ์ ์ ์๋ ์ปจํ
์ด๋ ์ด๋ฆ */ protected String name = null; /** * ์ปจํ
์ด๋์ ๋ถ๋ชจ ์ปจํ
์ด๋ */ protected Container parent = null; /** * Loader๋ฅผ ์ค์นํ ๋ ๊ตฌ์ฑ์ด ๋๋์ผ ํ ์ด๋ฒ์ด ํด๋์ค ๋ก๋ */ protected ClassLoader parentClassLoader = null; /** * ์ปจํ
์ด๋์ ๊ด๋ จ๋ Pipeline ๊ฐ์ฒด */ protected Pipeline pipeline = new StandardPipeline(this); /** * ์ปจํ
์ด๋์ ๊ด๋ จ๋ Realm */ protected Realm realm = null; /** * ์ปจํ
์ด๋์ ๊ด๋ จ๋ DirContect ๊ฐ์ฒด */ protected DirContext resources = null;๊ทผ๋ฐ ์ ๊ฐ์ ์ด๋ณด์๊ฒ๋ ์ ์ฃผ์ ์ผ๋ถ๋ ์คํ๋ ค ์ดํดํ๊ธฐ ํธํ๊ฒ ๋ง๋ค์ด ์ฃผ๋ ๊ฒ ๊ฐ์์.
์คํดํ ์ฌ์ง๊ฐ ์๋ ์ฃผ์
์๊น ์ ์ฝ๋์์ this.closed๊ฐ true์ด๋ฉด ๋ฐํ๋๋ค๋ ์ ํธ๋ฆฌํฐ ํจ์๊ฐ ๊ธฐ์ต๋๋์? ๊ทธ๋ฐ๋ฐ ํจ์๋ฅผ ๋ณด๋ฉด ์๋ฌด๊ฒ๋ ๋ฐํ๋์ง ์๊ณ ์์ด์. ์ฃผ์์ ๋ด๊ธด "์๋ชป๋ ์ ๋ณด"๋ก ๋ฐํ๋ ๊ฑฐ๋ผ ์๊ฐํ๋ 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 = duration; cdList.add(cd);}์ฌ๊ฒฌ: ์์ ๊ฐ์ ์ผ์ด ์ผ์ด๋๋ ์ด์ ๋ ์์ผ๊น..? ๊ตฌ์ฑ์๋ค์ด ์ฝ๋๋ฅผ ์์์น ๋ชปํ๊ฒ ์ง์ ํ์ ๊ณผ ์ด๋ฆ์ ์ ๋ขฐํ์ง ๋ชปํด์ ์ผ๊น? ์๋๋ฉด ์ฝ๋์ง๋ ์ฌ๋์ด CD ๊ฐ์ฒด๋ฅผ ์ง์ ๋ฐ๋๋ก ํ์ด์ผ ํ์๊น? ์๊ฐ์ด ๋ง์์ง๋ค.
์ด๋ ฅ์ ๊ธฐ๋กํ๋ ์ฃผ์
์ข ์ข ๋ชจ๋์ ํธ์งํ ๋ ์ฒซ๋จธ๋ฆฌ์ ๋ณ๊ฒฝ ์ด๋ ฅ์ ๋จ๊ฒจ์. ์์ ์๋ ๋ณ๊ฒฝ ์ด๋ ฅ์ ๋จ๊ธฐ๋ ๊ฒ์ด ๊ด๋ก์ด๊ณ ํ์ํ์ง๋ง, ์์ค ์ฝ๋ ๋ฒ์ ๊ด๋ฆฌ ์์คํ ์ ์ฌ์ฉํ๋ฉด์ ํ์ ์์ด์ก์ผ๋ ์ ๊ฑฐํ๋ ํธ์ด ์ข์์.
์์ผ๋ ๋ง๋ ํ ์ฃผ์
๋๋๋ก ์์ผ๋ ๋ง๋ ํ ์ฃผ์์ ์ ํด์. ๋๋ฌด ๋น์ฐํ ์ฌ์ค์ ์ธ๊ธํ์ฌ ์๋ก์ด ์ ๋ณด๋ฅผ ์ฃผ์ง ๋ชปํ๋ ์ฃผ์์ด์์.
// ๊ธฐ๋ณธ ์์ฑ์protected AnnualDateRule() {}// ์ ์ค ์ผ์private int dayOfMonth;์์ ๊ฐ์ ์ฃผ์์ด ๋ง์์ง๋ฉด ๋๋ฌด ์ง๋์น ์ฐธ๊ฒฌ์ด๋ผ ๊ฐ๋ฐ์๊ฐ ์ฃผ์์ ๋ฌด์ํ๋ ์ต๊ด์ ๋น ์ง ์ ์์ด์. ๊ทธ๋ฆฌ๊ณ ์ด๋ ์ฝ๋๊ฐ ๋ฐ๋๋ฉด์ ์ฃผ์์ด ๊ฑฐ์ง์ด ๋์ด ๋ฒ๋ ค์.
๋ฌด์์ด ์ก์
๋๋ก๋ Javadocs๋ ์ก์์ด์์. ๋ค์์ ์ ์๋ ค์ง ์คํ ์์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ ๊ฐ์ ธ์จ ์ฝ๋์์.
/** The name. */private String name;/** The version. */private String version;/** The licenceName. */private String licenceName;/** The Info */private String info;๊ฑฐ์ ๋ถ์ฌ๋ฃ๊ธฐํ ๊ฑฐ ๊ฐ์์. ๋ ์๊ฐ ์ฌ๊ธฐ์ ๋ฌด์จ ์ด์ต์ ์ป์ ์ ์์ด ๋ณด์ด๋์?
ํจ์๋ ๋ณ์๋ก ํํํ ์ ์๋ค๋ฉด ์ฃผ์์ ๋ฌ์ง ๋ง๋ผ
// ์ ์ญ ๋ชฉ๋ก<smodule>์ ์ํ๋ ๋ชจ๋์ด ์ฐ๋ฆฌ๊ฐ ์ํ ํ์ ์์คํ
์ ์์กดํ๋๊ฐ?if(smodule.getDependSubsystems().contains(subSysMod.getSubSystem()))<--- ๊ฐ์ ํ --->ArrayList moduleDependees = smodule.getDependSubsystems();String ourSubSystem = subSysMod.getSubSystem();if(moduleDependees.contains(ourSubSystem))์ ์ฝ๋๋ฅผ ๋ณด๋ฉด ์ฝ๋๋ฅผ ์์๋ณด๊ธฐ ํ๋ค์ด์ ์ฃผ์์ ๋ฃ์์ง๋ง, ์ฝ๋๋ฅผ ๊ฐ์ ํ๋ฉด ๊ตณ์ด ์ฃผ์์ด ํ์ ์์ด์. ๋ฌผ๋ก ์ ์๊ฐ ์ฃผ์์ ๋จผ์ ๋ฌ๊ณ ์ฃผ์์ ๋ง์ถฐ ์ฝ๋๋ฅผ ์์ฑํ์ ์๋ ์์ด์. ํ์ง๋ง ์์ ๊ฐ์ ์ฃผ์์ด ํ์ํ์ง ์๋๋ก ๊ฐ์ ํ๋๊ฒ ์ข์์.
์์น๋ฅผ ํ์ํ๋ ์ฃผ์
์์น๋ฅผ ํ์ํ๋ ค๊ณ "// Actions ///////////" ์ด๋ฐ์์ผ๋ก ์ฃผ์์ ๋ค๋ ๊ฒฝ์ฐ๊ฐ ์์ด์. ํด๋น ์ฃผ์ ๋ฐฐ๋ ์๋์ Action๋ค์ ๋ชจ์๋จ์ ๊ฑฐ ๊ฐ์์. ๋ค์ ////๊ฐ์ ๊ฑฐ๋ ๋๋ฌด ๋์ ๋๊ณ ๋ณ๋ฃจ๋ผ๊ณ ๋ ์๊ฐ ๋งํด์. ๊ทธ๋ฆฌ๊ณ ์ ๋ฐ ๋ฐฐ๋๋ ๋ฐ๋์ ํ์ํ ๋๋ง ๋๋ฌผ๊ฒ ์ฌ์ฉํ๋๊ฒ ์ข๋ค๊ณ ๋งํด์. ์ ๋ํ ์ ๋ฐ ๋ฐฐ๋๋ฅผ ์ ๋ช ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ ์ฐ๋ ๊ฑธ ๋ณธ์ ์ด ์์ด์.
๋ซ๋ ๊ดํธ์ ๋ค๋ ์ฃผ์
์ค์ฒฉ์ด ์ฌํ๊ณ ์ฅํฉํ ํจ์๋ผ๋ฉด ๋ซ๋ ๊ดํธ๊ฐ ์๋ฏธ๊ฐ ์์ ์ ์์ง๋ง, ์๊ณ ์บก์ํ๋ ํจ์๋ฅผ ์ ํธํ๋ ์ฐ๋ฆฌ๋ค์๊ฒ๋ ๊ทธ๋ด ํ๋ฅ ์ด ์ ์ด์. ๋ซ๋ ๊ดํธ์ ์ฃผ์์ ๋ฌ์์ผ๊ฒ ๋ค๋ ์๊ฐ์ด ๋ค๋ฉด ํจ์๋ฅผ ์ค์ด๋๋ก ์๋ํด๋ด์. ๋ค์ ์ฝ๋๊ฐ ๊ทธ ์์์์
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++; ... } // while System.out.println("wordCount = " + wordCount); System.out.println("charCount= " + charCount); System.out.println("lineCount = " + lineCount); } // try catch (IOException e) { System.err.println("์๋ฌ:" + e.getMessage()); } // catch } // main}๊ณต๋ก๋ฅผ ๋๋ฆฌ๊ฑฐ๋ ์ ์๋ฅผ ํ์ํ๋ ์ฃผ์
"/* ๋น๊ทผ์ด ์ถ๊ฐํจ */"๊ณผ ๊ฐ์ ์ฃผ์์ ๋์ด์ ํ์ ์์ด์. ๋ฒ์ ๊ด๋ฆฌ ์์คํ ์ ํตํด ๋๊ฐ ์ธ์ ๋ฌด์์ ์ถ๊ฐํ๋์ง ์ ์ ์์ผ๋๊น์.
์ฃผ์์ผ๋ก ์ฒ๋ฆฌํ ์ฝ๋
์ฃผ์์ผ๋ก ์ฒ๋ฆฌํ ์ฝ๋๋ ๋ฒ์ ๊ด๋ฆฌ ์์คํ ์ด ์๊ธฐ๋ฉด์ ๊ตณ์ด ๋จ๊ฒจ๋ ํ์๊ฐ ์์ด์. ๋ ์์๊ฒ ์ ๋ณด๋ฅผ ์ ๋ฌํ๊ธฐ ํ๋ค๊ฑฐ๋ ์. ๊ทผ๋ฐ ์ ๋ ์ฌ์ค ์ฝ๋ ์ด๋ ฅ ๋ณด๊ฒ ๋ค๊ณ ๋ฒ์ ๋๋ฆฌ๋ ๊ฒ๋ ํ๋ค๊ธด ํด์. ใ ใ
HTML ์ฃผ์
์ด๊ฑฐ๋ ์ง์ง ์ฃผ์์์ <p/>, <pre/>, " ๊ฐ์๊ฑฐ๋ก ์ฃผ์ ๋ค๋ ๊ฑฐ์์. ์ ์๊ฐ ์์ฒญ ํ์คํ๋ ๊ฑฐ์์. ์ ๋ ์ด๊ฑด ํ์ค์ค๋ฌ์์. ๊ตณ์ด ์์๋ ์๋ณด์ฌ์ค๊ฒ์. ์ ๋ง ํ์ํ ๊ฒฝ์ฐ๊ฐ ์์ ์๋ ์์๊ฑฐ ๊ฐ๊ธดํด์. ์๋ฅผ๋ค๋ฉด JS Docs์์ ์ปดํฌ๋ํธ ์ฌ์ฉ๋ฒ์ ์ ์ด์ค ๋์. ๊ทธ๋ด ๋๋ ๋ถ๋ช ์ฌ์ฉํ ์ ์๊ฒ ์ฃ ?
/** * Headless Select component using Render Props * * @example * ```jsx * <HeadlessSelect * options={['Apple', 'Banana', 'Orange']} * value={value} * onChange={setValue} * > * {({ value, open, toggle, select }) => ( * <div> * <button onClick={toggle}> * {value ?? 'Select a fruit'} * </button> * {open && ( * <ul> * {['Apple', 'Banana', 'Orange'].map((opt) => ( * <li key={opt} onClick={() => select(opt)}> * {opt} * </li> * ))} * </ul> * )} * </div> * )} * </HeadlessSelect> * ``` */์ ์ญ ์ ๋ณด
์ฃผ์์ ๋ฌ์์ผ ํ๋ค๋ฉด ๊ทผ์ฒ์ ์๋ ์ฝ๋๋ง ๊ธฐ์ ํ๋๊ฒ ์ข์์. ์ฝ๋ ์ผ๋ถ์ ์ฃผ์์ ๋ฌ๋ฉด์ ์์คํ ์ ์ ๋ฐ์ ์ธ ์ ๋ณด๋ฅผ ๊ธฐ์ ํ๋ฉด, ํด๋น ์ ๋ณด๊ฐ ๋ณํด๋ ์ถ์ ๋ ํ๋ค๊ณ ํต์ ๋ ๋ถ๊ฐํด์.
/** * ์ ํฉ์ฑ ํ
์คํธ๊ฐ ๋์ํ๋ ํฌํธ: 8082 * @param fitnessePort */public void setFitnessePort(int fitnessePort) { this.fitnessePort = fitnessePort;}๋๋ฌด ๋ง์ ์ ๋ณด
์ฃผ์์ ํฅ๋ฏธ๋ก์ด ์ญ์ฌ๋ ๊ด๋ จ ์๋ ์ ๋ณด๋ฅผ ์ฅํฉํ๊ฒ ๋์ด๋์ง ๋ง์ธ์. ๋ค์ ์์๋ฅผ ๋ณด๋ฉด RFC ๋ฒํธ๋ฅผ ์ ์ธํ๋ฉด ๋ ์์๊ฒ ๋ถํ์ํ ์ ๋ณด์ผ ๋ฟ์ด์์.
/* RFC 2045 - Multipurpose Internet Mail Extensions (MIME) 1๋ถ: ์ธํฐ๋ท ๋ฉ์์ง ๋ณธ์ฒด ํ์ 6.8์ . Base64 ๋ด์ฉ ์ ์ก ์ธ์ฝ๋ฉ(Content-Transfer-Encoding) ์ธ์ฝ๋ฉ ๊ณผ์ ์ ์
๋ ฅ ๋นํธ ์ค 24๋นํธ ๊ทธ๋ฃน์ ์ธ์ฝ๋ฉ๋ 4๊ธ์๋ก ๊ตฌ์ฑ๋ ์ถ๋ ฅ ๋ฌธ์์ด๋ก ํํํ๋ค. ์ผ์ชฝ์์ ์ค๋ฅธ์ชฝ์ผ๋ก ์งํํด๊ฐ๋ฉฐ, 3๊ฐ๋ฅผ ๋ฌถ์ด 8๋นํธ ์
๋ ฅ...*/๋ชจํธํ ๊ด๊ณ
์ฃผ์๊ณผ ์ฝ๋ ์ฌ์ด ๊ด๊ณ๊ฐ ๋ช ๋ฐฑํด์ผํด์. ๊ณต๋ค์ฌ ์ฃผ์์ ๋ฌ์๋ค๋ฉด ์ ์ด๋ ๋ ์๊ฐ ์ฃผ์๊ณผ ์ฝ๋๋ฅผ ์ฝ๊ณ ๋ฌด์จ ์๋ฆฌ์ธ์ง๋ ์์์ผ๊ฒ ์ฃ ?
/* * ๋ชจ๋ ํฝ์
์ ๋ด์ ๋งํผ ์ถฉ๋ถํ ๋ฐฐ์ด๋ก ์์ํ๋ค(์ฌ๊ธฐ์ ํํฐ ๋ฐ์ดํธ๋ฅผ ๋ํ๋ค). * ๊ทธ๋ฆฌ๊ณ ํค๋ ์ ๋ณด๋ฅผ ์ํด 200๋ฐ์ดํธ๋ฅผ ๋ํ๋ค. */this.pngBytes = new byte[((this.width + 1) * this.height * 3) + 200];์ ์ฝ๋์์ ํํฐ ๋ฐ์ดํธ๊ฐ ๋ญ๋ผ๊ณ ์๊ฐํ๋์? +1์ธ๊ฐ์? *3์ธ๊ฐ์? 200๋ฐ์ดํธ๋ ์ ๋ํ ๊น์? ์ฃผ์ ์์ฒด๊ฐ ๋ค์ ์ค๋ช ์ ์๊ตฌํ๊ฒ๋์.
ํจ์ ํค๋
์งง์ ํจ์๋ ๊ธด ์ค๋ช ์ด ํ์ ์์ด์. ์งง๊ณ ํ ๊ฐ์ง๋ง ์ํํ๋ฉฐ ์ด๋ฆ์ ์ ๋ถ์ธ ํจ์๊ฐ ์ฃผ์์ผ๋ก ํค๋๋ฅผ ์ถ๊ฐํ ํจ์๋ณด๋ค ๋ ์ข์์.
๋น๊ณต๊ฐ ์ฝ๋์์ Javadocs
๊ณต๊ฐ API๋ Javadocs๊ฐ ์ ์ฉํด์. ํ์ง๋ง ๊ณต๊ฐํ์ง ์์ ์ฝ๋๋ผ๋ฉด Javadocs๊ฐ ์ธ๋ชจ๊ฐ ์์ด์. ์คํ๋ ค Javadocs ์ฃผ์์ด ์๊ตฌํ๋ ํ์์ผ๋ก ์ธํด ์ฝ๋๋ง ์ฐ๋งํด์ ธ์.
์์
์๋ ์ฝ๋๋ ์ผํธ ๋ฒก์ด ํ์๋ค ์์์ ๋ฉ์ง ํํ๋ก ๋ฆฌํฉํ ๋งํ๋๋ฐ ์ฌ์ฉํ ์ฝ๋์์.
/** * ์ด ํด๋์ค๋ ์ฌ์ฉ์๊ฐ ์ง์ ํ ์ต๋ ๊ฐ๊น์ง ์์๋ฅผ ์์ฑํ๋ค. ์ฌ์ฉ๋ ์๊ณ ๋ฆฌ์ฆ์ * ์๋ผํ ์คํ
๋ค์ค์ ์ฒด๋ค. * <p> * ์๋ผํ ์คํ
๋ค์ค: ๊ธฐ์์ 276๋
์ ๋ฆฌ๋น์ ํค๋ ๋ค์์ ์ถ์ ... * ์ค๋ช
... * <p> * ์๊ณ ๋ฆฌ์ฆ์ ์๋นํ ๋จ์ํ๋ค. 2์์ ์์ํ๋ ์ ์ ๋ฐฐ์ด์ ๋์์ผ๋ก * 2์ ๋ฐฐ์๋ฅผ ๋ชจ๋ ์ ๊ฑฐํ๋ค. ๋ค์์ผ๋ก ๋จ์ ์ ์๋ฅผ ์ฐพ์ ์ด ์ ์์ ๋ฐฐ์๋ฅผ ๋ชจ๋ ์ง์ด๋ค. * ์ต๋ ๊ฐ์ ์ ๊ณฑ๊ทผ์ด ๋ ๋๊น์ง ์ด๋ฅผ ๋ฐ๋ณตํ๋ค. * * @author Alphonse * @version 13 Feb 2002 atp * */public class GeneratePrimes { /** * @param maxValue๋ ์์๋ฅผ ์ฐพ์๋ผ ์ต๋ ๊ฐ * @return int[] */ public static int[] generatePrimes(int maxValue) { if(maxValue >= 2) { // ์ ์ผํ๊ฒ ์ ํจํ ๊ฒฝ์ฐ // ์ ์ธ int s = maxValue + 1; // ๋ฐฐ์ด ํฌ๊ธฐ boolean[] f = new boolean[s]; int i; // ๋ฐฐ์ด์ ์ฐธ์ผ๋ก ์ด๊ธฐํ for(i=0; i<s; i++) { f[i] = true; } // ์์๊ฐ ์๋ ์๋ ค์ง ์ซ์๋ฅผ ์ ๊ฑฐ f[0] = f[1] = false; // ์ฒด int j; for(i=2; i<Math.sqrt(s)+1; i++) { if(f[i]) { // i๊ฐ ๋จ์์๋ ์ซ์๋ผ๋ฉด ์ด ์ซ์์ ๋ฐฐ์๋ฅผ ๊ตฌํ๋ค. for(j=i*2; j<s; j+=i) { f[j] = false; // ๋ฐฐ์๋ ์์๊ฐ ์๋๋ค. } } } // ์์ ๊ฐ์๋? int count = 0; for(i=0; i<s; i++) { if(f[i]) { count ++; // ์นด์ดํธ ์ฆ๊ฐ } } int[] primes = new int[count]; // ์์๋ฅผ ๊ฒฐ๊ณผ ๋ฐฐ์ด๋ก ์ด๋ํ๋ค. for(i=0, j=0; i<s; i++) { if(f[i]) { // ์์์ผ ๊ฒฝ์ฐ primes[j++] = i; } } return primes; // ์์ ๋ฐํ } else { // maxValue < 2 return new int[0]; // ์
๋ ฅ์ด ์๋ชป๋์ด ๋น์ด ์๋ ๋ฐฐ์ด์ ๋ฐํํ๋ค. } }}๊ทธ๋ฆฌ๊ณ ๋ค์ ์ฝ๋๊ฐ ๋ฆฌํฉํฐ๋งํ ๊ฒฐ๊ณผ์์. ์ฃผ์์ด ์๋นํ ์ค์ด๋ ๊ฒ์ ๋ณผ ์ ์์ ๊ฑฐ์์. ์ฃผ์์ด 2๊ฐ๋ฐ์ ์๋ค์.
/** * ์ด ํด๋์ค๋ ์ฌ์ฉ์๊ฐ ์ง์ ํ ์ต๋ ๊ฐ๊น์ง ์์๋ฅผ ๊ตฌํ๋ค. * ์๊ณ ๋ฆฌ์ฆ์ ์๋ผํ ์คํ
๋ค์ค์ ์ฒด๋ค. * 2์์ ์์ํ๋ ์ ์ ๋ฐฐ์ด์ ๋์์ผ๋ก ์์
ํ๋ค. * ์ฒ์์ผ๋ก ๋จ์ ์๋ ์ ์๋ฅผ ์ฐพ์ ๋ฐฐ์๋ฅผ ๋ชจ๋ ์ ๊ฑฐํ๋ค. * ๋ฐฐ์ด์ ๋ ์ด์ ๋ฐฐ์๊ฐ ์์ ๋๊น์ง ๋ฐ๋ณตํ๋ค. */public class PrimeGenerator { private static boolean[] crossedOut; private static int[] result; public static int[] generatePrimes(int maxValue) { if(maxValue < 2) { return new int[0]; } else { uncrossIntegersUpTo(maxValue); crossOutMultiples(); putUncrossedIntegersIntoResult(); return result; } } private static void uncrossIntegersUpTo(int maxValue) { crossedOut = new boolean[maxValue + 1]; for(int i=2; i<crossedOut.length; i++) { crossedOut[i] = false; } } private static void crossOutMultiples() { int limit = determineIterationLimit(); for(int i=2; i<=limit; i++) { if(notCrossed(i)) { crossOutMultiplesOf(i); } } } private static int determineIterationLimit() { // ๋ฐฐ์ด์ ์๋ ๋ชจ๋ ๋ฐฐ์๋ ๋ฐฐ์ด ํฌ๊ธฐ์ ์ ๊ณฑ๊ทผ๋ณด๋ค ์์ ์์์ ์ธ์๋ค. // ๋ฐ๋ผ์ ์ด ์ ๊ณฑ๊ทผ๋ณด๋ค ๋ ํฐ ์ซ์์ ๋ฐฐ์๋ ์ ๊ฑฐํ ํ์๊ฐ ์๋ค. double iterationLimit = Math.sqrt(crossedOut.length); return (int)iterationLimit; } private static void crossOutMultiplesOf(int i) { for(int multiple = i*2; multiple<crossedOut.length; multiple += i) { crossedOut[multiple] = true; } } private static boolean notCrossed(int i) { return crossedOut[i] == false; } private static void putUncrossedIntegersIntoResult() { result = new int[numberOfUncrossedIntegers()]; for(int j=0, i=2; i<crossedOut.length; i++) { if(notCrossed(i)) { result[j++] = i; } } } private static int numberOfUncrossedIntegers() { int count = 0; for(int i=2; i<crossedOut.length; i++) { if(notCrossed(i)) { count ++; } } return count; }}์ ์ฝ๋ ๋ฆฌํฉํฐ๋ง์ ๋ํด์ ์ ์๋ ๋ค์๊ณผ ๊ฐ์ด ๋งํด์.
์ฒซ ๋ฒ์งธ ์ฃผ์์ด generatePrimes ํจ์ ์์ฒด์ ํก์ฌํ๊ธฐ ๋๋ฌธ์ ์ค๋ณต์ด๋ผ๊ณ ์ฃผ์ฅํ ์ ์๋ค. ํ์ง๋ง ์ฃผ์์ด ์์ด ์๊ณ ๋ฆฌ์ฆ ์ดํดํ๊ธฐ ์ฌ์์ง๋ค๊ณ ์๊ฐํ์ฌ ๋จ๊ฒผ๋ค.
๋ ๋ฒ์งธ ์ฃผ์์ ํ์คํ ํ์ํ๋ค. ๋ฃจํ ํ๊ณ๊ฐ์ผ๋ก ์ ๊ณฑ๊ทผ์ ์ฌ์ฉํ ์ด์ ๋ฅผ ์ค๋ช ํ๋ค. ๋๋ก์๋ ๋ณ์ ์ด๋ฆ์ ๋ฐ๊พธ๊ฑฐ๋ ์ฝ๋ ๊ตฌ์กฐ๋ฅผ ์กฐ์ ํด ์ด์ ๋ฅผ ๋ช ํํ๊ฒ ์ค๋ช ํ ๋ฐฉ๋ฒ์ ์ฐพ์ง ๋ชปํ๋ค. ๋ ๋ค๋ฅธ ํํธ์ผ๋ก ์ ๊ณฑ๊ทผ์ ์ฌ์ฉ์ ๋๋ง์ ์๊ฐ์ผ์ง๋ ๋ชจ๋ฅด๊ฒ ๋ค. ์ ๊ณฑ๊ทผ๊น์ง๋ง ๋ฃจํ๋ฅผ ๋๋ฉด ์ ๋ง๋ก ์๊ฐ์ ์ ์ฝํ ๊น? ์ ๊ณฑ๊ทผ ๊ณ์ฐ์ ์คํ๋ ค ์๊ฐ์ด ๋ ๋ค์ง ์์๊น?
4์ฅ ๋ง๋ฌด๋ฆฌ
4์ฅ์ ๋ํด ๊ฐ๋ตํ๊ฒ ์๊ฐํ๋๋ฐ ๋์์ด ๋ง์ด ๋์ จ๋์? ์ ๋ ํ์ฅ ํ์ฅ ๋ณผ๋๋ง๋ค ์ ์ ์๊ฐ๊ณผ ์ฃผ์ฅ์ด ๋ ์ฌ๋ผ์. ์ด๋ฒ ์ฅ์ ๋์ฒด๋ก ๋ค ๋์ํด์. ๊ทธ๋ฐ๋ฐ ์ต๊ทผ์ ์ ๋ AI๋ก ์ฝ๋ฉ์ ํด๋ฆฐํ๊ณ ํจ์จ์ ์ผ๋ก ํ๊ธฐ์ํด ๊ณต๋ถํ๊ณ ์ ์ฉํด๋ณด๊ณ ์์ด์. ๊ทธ๋ฐ์ง ์ ์ฃผ์ฅ๋ค ์ค์ ๊ณต๊ฐ API๊ฐ ์๋๋ผ๋ฉด Javadocs๋ฅผ ์์ ๋ ๊ฒ์ด ์ข์์ง ์๊ฐํด๋ณด๊ฒ ๋๋ค์. ์ฌ๋์ด ์ฝ๋ฉ์ ํ๋ฉด ๊ฐ์ ํ์๋ค์ด ์๋ก ๋ง๋ api๋ฅผ ์ฌ์ฉํ๋ค๋ฉด, ๋ด๋ถ API๋ผ๋ Javadocs๊ฐ ๋์์ด ๋ ๊ฑฐ ๊ฐ๋ค๊ณ ์๊ฐํด์. ๊ทธ๋ฐ๋ฐ ๊ทธ ํจ์ฉ์ฑ์ ๋ํด์๋ ๋ค์ธ ๋ ธ๋ ฅ๋งํผ ์๊ฐ์ ๊ฐ์น๊ฐ ์์๊น ์๊ฐํ๋ฉด ๊ธ์.. ๋ ์๊ฐํด๋ด์ผํ ๊ฑฐ ๊ฐ์์.(๋ฌผ๋ก AI๋ก Javadocs ๋๋ฑ ๋ง๋๋๊น ํจ๋ฌ๋ค์์ด ๋ฐ๋๊น์??) ๊ทธ๋ฆฌ๊ณ AI๊ฐ ์ฝ๋ฉ์ ํ๋ฉด Javadocs๊ฐ ์ฝ๋ฉํ๋๋ฐ ๋ ๋์์ ์ค๊น?๋ผ๋ ์๊ฐ์ ํ๋ฉด์ ์๊น์ด ๋ด ํ ํฐ์ ์์ฐฝ ๊ฐ์๋จน์ ๊ฒ ๊ฐ์ ์๊ฐ๋ ํ๊ฒ ๋๋ค์. ๋ฌผ๋ก ๋ ๋ค๋ฅธ ๊ด์ ์์๋ ๊ฒฐ๊ตญ ์ ์ฒด ์ฝ๋ ๋์์ธ์ ๋ด๊ฐ ํ๋ ๊ฒ์ด๋ AI๊ฐ Javadocs๋ฅผ ์๋ ๋ชจ๋ฅด๋ ํฌ๊ฒ ์ํฅ์ด ์์ ๊ฒ ๊ฐ๊ธฐ๋ ํด์. ์๋ฌดํผ ๊ทธ๋ฐ ์๊ฐ์ ํ๋ต๋๋ค.
5์ฅ. ํ์ ๋ง์ถ๊ธฐ
๋๊ป์ ์ด์์ ๋ ๋ ์๋ค์ด ์ฝ๋๊ฐ ๊น๋, ์ผ๊ด, ๊ผผ๊ผผํ๋ค๊ณ ๊ฐํํ๊ณ , ์ง์ ์ ์ฐํ๋ค๊ณ ํ๋ณตํ๋ฉด ์ข๊ฒ ์ฃ ? ๊ทธ๋ฆฌ๊ณ ๋ชจ๋์ ์ฝ์ผ๋ฉฐ ๋ ๋์ด ํ๋ฅ๊ทธ๋ ๋๋ผ๊ณ ์ ๋ฌธ๊ฐ๊ฐ ์งฐ๋ค๋ ์ธ์์ ์ฌ์ด์ฃผ๋ฉด ์ข์๊ฑฐ์์. ๋ฐ๋๋ก ์ ์ทจํ ์ฌ๋์ด ์ฝ๋๋ฅผ ์ง ๊ฑฐ์ฒ๋ผ ์ด์์ ํด ๋ณด์ด๋ฉด ๋ ์๋ค์ ํ๋ก์ ํธ์ ๋ค๋ฅธ ์ธก๋ฉด๋ค๋ ๋ฌด์ฑ์ํ ํ๋๋ก ์ฒ๋ฆฌํ๋ค๊ณ ์๊ฐํ ๊ฑฐ์์.
์ฐ๋ฆฌ๋ ํ๋ก๊ทธ๋๋จธ(์ ๋ฌธ๊ฐ!)์ด๊ธฐ ๋๋ฌธ์ ํ์์ ๊น๋ํ๊ฒ ๋ง์ถฐ ์ฝ๋๋ฅผ ์ง์ผํด์. ๊ทธ๋์ ์ฝ๋ ํ์์ ๋ง์ถ๊ธฐ์ํ ๊ฐ๋จํ ๊ท์น์ ์ ํ๊ณ ๊ทธ ๊ท์น์ ์ฐฉ์คํ ๋ฐ๋ผ์ผํด์.
ํ์์ ๋ง์ถ๋ ๋ชฉ์
์ฝ๋ ํ์์ ์ค์ํด์! '๋์๊ฐ๋ '์ฝ๋'๊ฐ ๊ฐ๋ฐ์์ ์ผ์ฐจ์ ์ธ ์๋ฌด๋ผ ์ฌ๊ธธ ์ ๋ ์์ง๋ง, ์ ์๋ ์์ฌ์ํต์ด ์ ๋ฌธ ๊ฐ๋ฐ์์ ์ผ์ฐจ์ ์ธ ์๋ฌด๋ผ ์๊ฐํด์. ๊ทธ๋ฆฌ๊ณ ์์ฌ์ํต์ ์ผํ์ผ๋ก ์ฝ๋ ํ์์ด ์์ด์. ์ฝ๋๋ ๊ณ์ ๋ฐ๋๋๋ผ๋ ๊ฐ๋ฐ์์ ์คํ์ผ๊ณผ ๊ท์จ์ ์ฌ๋ผ์ง์ง ์๊ณ ๊ฐ๋ ์ฑ์ ์ํฅ์ ์ค ๋ฟ๋ง์๋๋ผ, ์ ์ง ๋ณด์์ฑ๊ณผ ํ์ฅ์ฑ๊น์ง ์ํฅ์ ์ค์.
์ธ๋ก ํ์ ๋ง์ถ๊ธฐ
์ ์ ํ ํ ๊ธธ์ด๋ ๋ช์ค์ด ์ ๋ฌํ ๊น์? ์ ์๊ฐ ์๋ ์ ์กฐ์ฌํด๋ณด๋ ๋ค์๊ณผ ๊ฐ์๋ค๊ณ ํด์.

์ ๋ช
ํ ํ๋ก์ ํธ๋ค์ ํ์ผ๋ค์ ๋ผ์ธ ์ ๋ถํฌ๋ฅผ ๋ฝ์ ๊ทธ๋ฆผ์ด์์. ์์ ์ธ๋ก์ ์ ์ต์์ ์ต๋ ๋ผ์ธ ์๋ฅผ ๋ํ๋ด๊ณ , ๋๊บผ์ด ์ธ๋ก ์ (์์)๋ ํ์คํธ์ฐจ, ์์ ๊ฐ์ด๋ฐ๋ ํ๊ท ์ ๋ํ๋ด์.
์์ ํ๊ฐ ๋งํด์ฃผ๋ ์ฌ์ค์ 500์ค์ ๋์ง ์๊ณ ๋๋ถ๋ถ 200์ค ์ ๋์ธ ํ์ผ๋ก๋ ์ปค๋ค๋ ์์คํ
์ ๊ตฌ์ถํ ์ ์๋ค๋ ์ฌ์ค์ด์์. ๋ฐ๋์ ์งํฌ ์๊ฒฉํ ๊ท์น์ ์๋์ง๋ง 200์ค ์ ๋๋ฅผ ๋ฐ๋์งํ ๊ท์น์ผ๋ก ์ผ์ผ๋ฉด ์ข์์. ํนํ ์์ฆ ์๋์ ๋ชจ๋ํฐ ํ๋ฉด์ด ํผ์งํ๊ณ , IDE๋ ์ข์์ 200์ค์ด ๋ง์ ์ค์ผ ์๋ ์๋ค๋ ์๊ฐ๋ ๋ค์ด์.
์ด์ ๋ณธ๊ฒฉ์ ์ผ๋ก ์ธ๋ก ํ์์ ๋ง์ถ๋ ๋ฐฉ๋ฒ๋ค์ ๋ํด์ ํ๋์ฉ ์๊ฐํ ๊ฒ์.
์ ๋ฌธ ๊ธฐ์ฌ์ฒ๋ผ ์์ฑํ๋ผ
์ข์ ์ ๋ฌธ ๊ธฐ์ฌ๋ ์์์ ์๋๋ก ์ ์ฒด์ ์ธ ๋ด์ฉ์ด ๋์ค๋ฉฐ ์ ์ ์ธ์ธํ ์ฌ์ค๋ค์ด ๋๋ฌ๋์. ์์ค ํ์ผ๋ ์ ๋ฌธ ๊ธฐ์ฌ์ ๋น์ทํ๊ฒ ์์ฑํ๋ฉด ์ข์์. ๋ชจ๋์ ์๋จ์ ๋ณด๋ฉด ๋ฌด์จ ๋ด์ฉ์ด ๋์ฌ์ง ์์ธก์ด๋์ด ๋ด๊ฐ ์ฐพ๋ ๋ชจ๋์ธ์ง ํ๋จํ ์ ์์ด์ผ ํ๊ณ , ์๋๋ก ๋ด๋ ค๊ฐ์๋ก ์๋๋ฅผ ์ธ์ธํ๊ฒ ๋ฌ์ฌํด์ผํด์. ๊ทธ๋ฆฌ๊ณ ๋ง์ง๋ง์๋ ๊ฐ์ฅ ์ ์ฐจ์ ํจ์์ ์ธ๋ถ ๋ด์ญ์ด ๋์ค๊ณ ์.
๊ฐ๋ ์ ๋น ํ์ผ๋ก ๋ถ๋ฆฌํ๋ผ
๊ฑฐ์ ๋ชจ๋ ์ฝ๋๋ ์ข์์ ์ฐ๋ก, ์์์ ์๋๋ก ์ฝ์ด์. ๊ฐ ํ์ ์์์ด๋ ์ ์ ๋ํ๋ด๊ณ , ์ผ๋ จ์ ํ ๋ฌถ์์ ํ๋์ ์๊ฐ์ ํํํด์. ๊ทธ๋ฆฌ๊ณ ์๊ฐ ์ฌ์ด๋ ๋น ํ์ ๋ฃ์ด ๋ถ๋ฆฌํด์ผ ํด์.
package fitnesse.wikitext.widgets;import java.util.regex.*;public class BoldWidget extends ParentWidget { public static final String REGEXP = "'''.+?'''"; private static final Pattern pattern = Pattern.compile("'''(.+?)'''", Pattern.MULTILINE + Pattern.DOTALL ); public BoldWidget(ParentWidget parent, String text) throws Exception { super(parent); Matcher match = pattern.matcher(text); match.find(); addChildWidgets(match.group(1)); } public String render() throws Exception { StringBuffer html = new StringBuffer("<b>"); html.append(childHtml()).append("</b>"); return html.toString(); } }์ ์ฝ๋๋ฅผ ๋ณด๋ฉด ํจํค์ง ์ ์ธ๋ถ, import ๋ฌธ, ๊ฐ ํจ์ ์ฌ์ด์ ๋น ํ์ด ๋ค์ด๊ฐ์. ๊ฐ๋จํ ๊ท์น์ด์ง๋ง ์ธ๋ก ๋ ์ด์์์ ๋ง์ ์ํฅ์ ์ค์. ๋น ํ์ ์๋ก์ด ๊ฐ๋ ์ ์์ํ๋ค๋ ์๊ฐ์ ๋จ์์์. ๊ทธ๋ฆฌ๊ณ ์ฝ๋๋ฅผ ์ฝ์ด ๋ด๋ ค๊ฐ๋ค ๋ณด๋ฉด ๋น ํ ๋ฐ๋ก ๋ค์ ์ค์ ๋๊ธธ์ด ๋ฉ์ถ์ฃ . ๋ง์ฝ ์ ์ฝ๋๋ฅผ ๋น ํ ์์ด ๋ถ์ฌ ๋ณด์ธ์. ์ํธ๋ฌธ ์ฒ๋ผ ๋ณด์ผ๊ฑฐ์์.
์ธ๋ก ๋ฐ์ง๋
์ค๋ฐ๊ฟ์ด ๊ฐ๋ ์ ๋ถ๋ฆฌํ๋ค๋ฉด ์ธ๋ก ๋ฐ์ง๋๋ ์ฐ๊ด์ฑ์ ์๋ฏธํด์. ์๋ก ๋ฐ์ ํ ์ฝ๋๋ ์ธ๋ก๋ก ๊ฐ๊น์ด ๋์์ผ ํ๋ค๋ ๊ฒ์ ๋งํด์.
public class ReporterConfig { /** * The class name of the reporter listener */ private String m_className; /** * The properties of the reporter listener */ private List<Property> m_properties = new ArrayList<Property>(); public void addProperty(Property property) { m_properties.add(property); }}์ ์ฝ๋์ ์๋ ์ฝ๋๋ฅผ ๋น๊ตํด๋ด์. ์ ์ฝ๋๋ ์๋ฏธ ์๋ ์ฃผ์์ผ๋ก ์ฝ๋ ํ์ ๋จ์ด๋จ๋ ธ๊ณ ์๋ํ์ ์ฃผ์์ด ์์ด์. ์๋ง ์๋ ์ฝ๋๊ฐ ๋ ์ฌ์ธ๊ฑฐ์์. ๋จธ๋ฆฌ๋ ๋์ ์์ง์ผ ํ์๋ ์๊ณ , ๋ณ์ 2๊ฐ์ ๋ฉ์๋ 1๊ฐ๋ผ๋ ์ฌ์ค์ด ๋ฐ๋ก ๋ณด์ฌ์.
public class ReporterConfig { private String m_className; private List<Property> m_properties = new ArrayList<Property>(); public void addProperty(Property property) { m_properties.add(property); }}์์ง ๊ฑฐ๋ฆฌ
ํจ์ ์ฐ๊ด ๊ด๊ณ์ ๋์ ๋ฐฉ์์ ์ดํดํ๋ ค๊ณ ์ด ํจ์์์ ์ ํจ์๋ก ์ค๊ฐ๋ฉฐ ์์ค ํ์ผ์ ์์๋๋ก ๋ค์ง๊ณ ๋บ๋บ์ด๋ฅผ ๋์์ผ๋ ๋ฏธ๋ก ๊ฐ์ ์ฝ๋ ๋๋ฌธ์ ํผ๋๋ง ๊ฐ์ค๋ ๊ฒฝํ์ด ์๋์? (์ ์์ ์ React 19 ํ์ ํ๋ คํ๋๋ฐ ๋๋ฌด ๋ฏธ๋ก๊ฐ์์ด์.) ๊ฒฐ์ฝ ๋ฌ๊ฐ์ง ์์ ๊ฒฝํ์ด์์. ์์คํ ์ ์ดํดํ๊ณ ์ถ์ด๋ ์ด ์กฐ๊ฐ ์ ์กฐ๊ฐ์ด ์ด๋์ ์๋์ง ์ฐพ๊ณ ๊ธฐ์ตํ๋๋ผ ์๊ฐ๊ณผ ๋ ธ๋ ฅ์ ๋ค ์จ์.
์๋ก ๋ฐ์ ํ ๊ฐ๋ ์ ์ธ๋ก๋ก ๊ฐ๊น์ด ๋ฌ์ผํด์. ๋ฌผ๋ก ๋ ๊ฐ๋ ์ด ์๋ก ๋ค๋ฅธ ํ์ผ์ ์ํ๋ฉด ๊ท์น์ด ํตํ์ง ์์์. ํ์ง๋ง ํ๋นํ ๊ทผ๊ฑฐ๊ฐ ์๋ค๋ฉด ์๋ก ๋ฐ์ ํ ๊ฐ๋ ์ ํ ํ์ผ์ ์๋๊ฒ ์ข์์. ์ด๊ฒ protected ๋ณ์๋ฅผ ํผํด์ผํ๋ ์ด์ ์ค ํ๋์์(์๋ฐ์ ์ ๊ทผ ์ ์ด์ protected๋ ์์ ํด๋์ค์์ ์ ๊ทผํ๋๊น ์ฝ๋ ํ์ ์ด์ง๋ฌ์์ง! ์ธ์ ? ใ ์ธ์ ).
์ฆ, ๊ฐ์ ํ์ผ์ ์ํ ์ ๋๋ก ๋ฐ์ ํ ๋ ๊ฐ๋ ์ ์ธ๋ก ๊ฑฐ๋ฆฌ๋ก ์ฐ๊ด์ฑ์ ํํํด์. ์ฌ๊ธฐ์ "์ฐ๊ด์ฑ"์ด๋ "ํ ๊ฐ๋ ์ ์ดํดํ๋ ๋ฐ ๋ค๋ฅธ ๊ฐ๋ ์ด ์ค์ํ ์ ๋"์์
์์ง ๊ฑฐ๋ฆฌ ์์
๋ณ์์ ํจ์๋ ์ฌ์ฉ๋๋ ์์น์ ์ต๋ํ ๊ฐ๊น๊ฒ ์ ์
์ง์ญ ๋ณ์๋ ์ฒ์ ์ฌ์ฉํ๊ธฐ ์ง์ ์ ์ ์ธ
๋น๊ณต๊ฐ ํจ์๋ ์ฒ์ ํธ์ถํ ์งํ์ ์ ์ (์กฐ๊ธ๋ง ๋ด๋ ค๊ฐ๋ฉด ๋ณด์ด๊ฒ), ๊ฐ๋ฅํ๋ฉด ํธ์ถํ๋ ํจ์๋ฅผ ๋จผ์ ๋ฐฐ์นํ์.
์ธ์คํด์ค ๋ณ์๋ ๋งจ ์ฒ์์(C++์์๋ ๋ณดํต ๋ง์ง๋ง์) ์ ์ธํ๋ค.(์ ์๋ ค์ง ์์น์ ๋ชจ์ผ๋๊ฒ ์ค์)
์์๋ ์ ์ฐจ์ ํจ์์ ๋ฌปํ์ง ๋ง๋ผ(์์๋ ๊ณ ์ฐจ์ ํจ์์ ๋๊ณ , ์ ์ฐจ์ ํจ์์๋ ์ธ์๋ก ๋๊ฒจ๋ผ)
๊ฐ๋ ์ ์ ์ฌ์ฑ์ด ๋์ ์ฝ๋๋ ๊ฐ๊น์ด ๋ฐฐ์นํ๋ค. (A์ฝ๋๊ฐ B์ฝ๋๋ฅผ ์ฐ๋ฉด ์๋ก ์ข ์๋๊ธฐ ๋๋ฌธ์ ์นํ๋๊ฐ ๋๋ค.)
์ธ๋ก ์์
์ผ๋ฐ์ ์ผ๋ก ํจ์ ํธ์ถ ์ข ์์ฑ์ ์๋ ๋ฐฉํฅ์ผ๋ก ์ ์งํด์. ์ฆ, ํธ์ถ๋๋ ํจ์๊ฐ ํธ์ถํ๋ ํจ์๋ณด๋ค ๋์ค์ ๋ฐฐ์น๋์(C, C++์ ๋จผ์ ์ ์ํ๋ ๊ฒฝ์ฐ ๋ง์). ๊ทธ๋ฌ๋ฉด ์์ค ์ฝ๋ ๋ชจ๋์ด ๊ณ ์ฐจ์์์ ์ ์ฐจ์์ผ๋ก ์์ฐ์ค๋ฝ๊ฒ ๋ด๋ ค๊ฐ์. ๋ง์น ์ ๋ฌธ ๊ธฐ์ฌ์์ ์ค์ํ ๊ฐ๋ ์ ๊ฐ์ฅ ๋จผ์ ํํํ๊ณ ์ธ์ธํ ๋ด์ฉ์ ๋ง์ง๋ง์ ํํํ๋ฏ์ด์.
๊ฐ๋ก ํ์ ๋ง์ถ๊ธฐ
ํ ํ์ ๊ฐ๋ก๋ก ์ผ๋ง๋ ๊ธธ์ด์ผ ์ ๋นํ ๊น์? ์์์์ ๊ฐ์ด ๋ถ์ํด๋ด์.

์ ๊ทธ๋ฆผ์ 7๊ฐ ์ ๋ช ํ๋ก์ ํธ์ ์๋ฐ ๋ผ์ธ์ ๊ฐ๋ก ๊ธธ์ด ๋ถํฌ๋์์.๊ฒฐ๊ณผ๊ฐ ์๋นํ ๊ท์น์ ์ด์์. 20-60์ ์ฌ์ด์ธ ํ์ด ์ด ํ์์ 40%์ ๋ ๋์. 10์ ๋ฏธ๋ง์ 30%์ ๋๋ก ๋ณด์ด๊ณ ์. ์ฆ 60์ ์ดํ๊ฐ 70%๊ฐ๊น์ด ์ฐจ์งํ๋ค์. 80์ ์ดํ๋ 10%์ ๋๊ฐ ๋๊ณ ์. ์์ฆ์ ๋ชจ๋ํฐ๋ ํฌ๊ณ ํด์ ์ข๋ ๋ง์๋ ๋ ๊ฒ ๊ฐ์์. ์ ์๋ 100์~120์ ์ ๋๊น์ง ์ ํ ๋๋๊ฒ ๊ด์ฐฎ์ ๊ฒ ๊ฐ๋ค๊ณ ๋งํด์.
์ด์ ๊ฐ๋ก ํ์ ๋ง์ถ๋ ๋ฐฉ๋ฒ๋ค์ ๋ํด์ ์๊ฐํ ๊ฒ์.
๊ฐ๋ก ๊ณต๋ฐฑ๊ณผ ๋ฐ์ง๋
๊ฐ๋ก๋ก๋ ๊ณต๋ฐฑ์ ์ฌ์ฉํด ๋ฐ์ ํ ๊ฐ๋ ๊ณผ ๋์จํ ๊ฐ๋ ์ ํํํด์.
private void measureLine(String line) { lineCount++; int lineSize = line.length(); totalChars += lineSize; lineWidthHistogram.addLine(lineSize, lineCount); recordWidestLine(lineSize);}์ ํจ์๋ฅผ ๋ณด๋ฉด ํ ๋น ์ฐ์ฐ์๋ฅผ ๊ฐ์กฐํ๋ ค๊ณ ์๋ค์ ๊ณต๋ฐฑ์ ์คฌ์ด์. ํ ๋น ์ฐ์ฐ์๋ ์ผ์ชฝ ์์์ ์ค๋ฅธ์ชฝ ์์๊ฐ ํ์คํ ๋๋์ด์. ๊ทธ๋์ ๊ณต๋ฐฑ์ ๋ฃ์ผ๋ฉด ๋ ๋ถ๋ช ํด์ ธ์. ๋ฐ๋ฉด์ ํจ์ ์ด๋ฆ๊ณผ ์ด์ด์ง๋ ๊ดํธ ์ฌ์ด์๋ ๊ณต๋ฐฑ์ด ์์ด์. ์๋ํ๋ฉด ๊ณต๋ฐฑ์ ๋ฃ์ผ๋ฉด ๋ณ๊ฐ๋ก ๋ณด์ด๊ธฐ ๋๋ฌธ์ด์์. ๊ทธ๋ฆฌ๊ณ ์ธ์ ์ฌ์ด์ ์ผํ ๋ค์์๋ ๊ณต๋ฐฑ์ ์ค์ ์ธ์๊ฐ ๋ณ๊ฐ๋ผ๋ ์ฌ์ค์ ๊ฐ์กฐํด์. (์์ฆ์ lint, prettier๊ฐ์ ๊ฑธ๋ก ์๋์ผ๋ก ๋ค๋๋ค. ๊ท์น ์ค์ ๋ง ์ ํ๋ฉด ๋๋ค.)
public class Quadratic { public static double root1(double a, double b, double c) { double determinant = determinant(a, b, c); return (-b + Math.sqrt(determinant)) / (2*a); } public static double root2(int a, int b, int c) { double determinant = determinant(a, b, c); return (-b - Math.sqrt(determinant)) / (2*a); } private static double determinant(double a, double b, double c) { return b*b - 4*a*c; }}์ ์ฝ๋๋ฅผ ๋ณด๋ฉด ์์ ์ฝ๊ธฐ๊ฐ ํธํด์. ์น์ ์ฌ์ด๋ ๊ณต๋ฐฑ์ด ์์ด์. ๊ณฑ์ ์ ์ฐ์ ์์๊ฐ ๊ฐ์ฅ ๋๊ธฐ ๋๋ฌธ์ด์์. ํ์ง๋ง ํญ ์ฌ์ด์๋ ๊ณต๋ฐฑ์ด ๋ค์ด๊ฐ์. ๋ง์ ๊ณผ ๋บ์ ์ ๊ณฑ์ ๋ณด๋ค ์ฐ์ ์์๊ฐ ๋ฎ๊ธฐ ๋๋ฌธ์ด์์.
๊ฐ๋ก์ ๋ ฌ
์ ์๋ ์ด์ ๋ธ๋ฆฌ์ด ์์ ํน์ ๊ตฌ์กฐ๋ฅผ ๊ฐ์กฐํ๊ณ ์ ๊ฐ๋ก ์ ๋ ฌ์ ์ฌ์ฉํ๋ฐ์. ๋ค์๊ณผ ๊ฐ์ด ๋ง์ด์ฃ
public class FitNesseExpediter implements ResponseSender{ private Socket socket; private InputStream input; private OutputStream output; private Request request; private Response response; private FitNesseContext context; protected long requestParsingTimeLimit; private long requestProgress; private long requestParsingDeadline; private boolean hasError; public FitNesseExpediter(Socket s, FitNesseContext context) throws Exception { this.context = context; socket = s; input = s.getInputStream(); output = s.getOutputStream(); requestParsingTimeLimit = 10000; }๊ทธ๋ฐ๋ฐ ์์ ๊ฐ์ ์ ๋ ฌ์ด ๋ณ๋ก ์ข์ง ์๋ค๋ ๊ฒ์ ๊นจ๋ฌ์๋ฐ์. ์๋ฑํ ๋ถ๋ถ์ ๊ฐ์กฐํด์ ์ง์ง ์๋๊ฐ ๊ฐ๋ ค์ ธ์. ์๋ฅผ ๋ค๋ฉด, ์ ์ ์ธ๋ถ๋ฅผ ์ฝ๋ค ๋ณด๋ฉด ๋ณ์ ์ ํ์ ๋ฌด์ํ๊ณ ๋ณ์ ์ด๋ฆ๋ถํฐ ์ฝ๊ฒ ๋์. ๊ทธ๋ฆฌ๊ณ ํ ๋น ์ฐ์ฐ์๋ ๋์๊ฐ์ง ์๊ณ ์ค๋ฅธ์ชฝ ํผ์ฐ์ฐ์๋ง ๋์ ๊ฐ์. ๋ฌด์๋ณด๋ค ๋๋ถ๋ถ ์ฝ๋ ์ ๋ ฌ ๋๊ตฌ๋ ์์ ๊ฐ์ ๊ณต๋ฐฑ์ ๋ฌด์ํด์. ์ฝ๋๋ฅผ ์ ๋ ฌํ๋ฉด ์คํ๋ ค ์ค๋ํ ๊ฒฐํจ์ ์ฐพ๊ธฐ ํ๋ค์ด์ ธ์.
๋ง์ฝ ์ ๋ ฌ์ด ํ์ํ ์ ๋๋ก ๊ธธ๋ค๋ฉด ๋ฌธ์ ๋ ๋ชฉ๋ก์ ๊ธธ์ด์ง ์ ๋ ฌ ๋ถ์กฑ์ด ์๋์์. ์ฝ๋ ์ ์ธ๋ถ๊ฐ ๊ธธ๋ค๋ฉด ํด๋์ค๋ฅผ ์ชผ๊ฐ์ผ ํ๋ค๋ ์๋ฏธ์์.
๋ค์ฌ์ฐ๊ธฐ
๋ค์ฌ์ฐ๊ธฐ๋ฅผ ํ์ง ์์ผ๋ฉด ์ฝ๋๋ฅผ ์ฝ๊ธฐ ํ๋ค์ด์ ธ์. ์ด๊ฑด ๊ตณ์ด ์ค๋ช ์ํด๋ ์ ๊ฒ ๊ฐ์์ ๋์ด๊ฐ๊ฒ์. if๋ฌธ ์ฌ๋ฌ๊ฐ์ธ๋ฐ ๋ชจ๋ ํ์ค์ ์๋ค๊ณ ์๊ฐํด๋ด์. ์ผ๋ง๋ ๋์ฐํด์. ์ ์๋ ๊ฐ๋ 1์ค๋ก๋ ๊ฐ๋ฅํ ์งง์ ์ฝ๋๋ ๋ค์ฌ์ฐ๊ธฐ ์์ฐ๋ ์ ํน์ ๋น ์ง๋ค๊ณ ํด์. ๊ทธ์น๋ง ๊ฒฐ๊ตญ ์์ ์ผ๋ก ๋์๊ฐ ๋ค์ฌ์ฐ๊ธฐ๋ฅผ ํ๋ค๊ณ ํด์.
ํ ๊ท์น
ํ๋ก๊ทธ๋๋จธ๋ก์ ๊ฐ์ ์ ํธํ๋ ๊ท์น์ด ์์ด์. ํ์ง๋ง ์์ ์ด ์ ํธํด์ผ ํ ๊ท์น์ ํ ๊ท์น์ด์์. ์ด์ฒํผ ๋๋ถ๋ถ ์ ํ ๊ท์น์ IDE์ฝ๋ ํ์๊ธฐ๋ก ์ค์ ํ ํ ์ฌ์ฉํ๊ธฐ๋ ํด์ ์ด๋ ต์ง ์์์. ๊ทธ๋ฆฌ๊ณ ์ ์๋ ํ ๊ท์น์ด ๋ง์์ ์๋ค์ด๋ ํ ๊ท์น์ ๋ฐ๋ผ ์ฝ๋๋ฅผ ๊ตฌํํ๋ค๊ณ ํด์.
๋ฐฅ ์์ ์จ์ ํ์ ๊ท์น
์๋ ์ฝ๋๋ ๋ฐฅ ์์ ์จ์ ํ์์ ์ ๋ํ๋ด๋ ํ์ค ๋ฌธ์ ์์ค์ด๋ผ๊ณ ์์ ํ๋ ์ฝ๋์์.
public class CodeAnalyzer implements JavaFileAnalysis { private int lineCount; private int maxLineWidth; private int widestLineNumber; private LineWidthHistogram lineWidthHistogram; private int totalChars; public CodeAnalyzer() { lineWidthHistogram = new LineWidthHistogram(); } public static List<File> findJavaFiles(File parentDirectory) { List<File> files = new ArrayList<File>(); findJavaFiles(parentDirectory, files); return files; } private static void findJavaFiles(File parentDirectory, List<File> files) { for (File file : parentDirectory.listFiles()) { if (file.getName().endsWith(".java")) files.add(file); else if (file.isDirectory()) findJavaFiles(file, files); } } public void analyzeFile(File javaFile) throws Exception { BufferedReader br = new BufferedReader(new FileReader(javaFile)); String line; while ((line = br.readLine()) != null) measureLine(line); } private void measureLine(String line) { lineCount++; int lineSize = line.length(); totalChars += lineSize; lineWidthHistogram.addLine(lineSize, lineCount); recordWidestLine(lineSize); } private void recordWidestLine(int lineSize) { if (lineSize > maxLineWidth) { maxLineWidth = lineSize; widestLineNumber = lineCount; } } public int getLineCount() { return lineCount; } public int getMaxLineWidth() { return maxLineWidth; } public int getWidestLineNumber() { return widestLineNumber; } public LineWidthHistogram getLineWidthHistogram() { return lineWidthHistogram; } public double getMeanLineWidth() { return (double)totalChars/lineCount; } public int getMedianLineWidth() { Integer[] sortedWidths = getSortedWidths(); int cumulativeLineCount = 0; for (int width : sortedWidths) { cumulativeLineCount += lineCountForWidth(width); if (cumulativeLineCount > lineCount/2) return width; } throw new Error("Cannot get here"); } private int lineCountForWidth(int width) { return lineWidthHistogram.getLinesforWidth(width).size(); } private Integer[] getSortedWidths() { Set<Integer> widths = lineWidthHistogram.getWidths(); Integer[] sortedWidths = (widths.toArray(new Integer[0])); Arrays.sort(sortedWidths); return sortedWidths; } }5์ฅ ๋ง๋ฌด๋ฆฌ
5์ฅ์์๋ ์ฝ๋ ํ์๋ค์ ๋ํด์ ์ด์ผ๊ธฐํด๋ดค์ด์. ๊ทธ๋ฐ๋ฐ 5์ฅ์ ํ์๋ค์ ๋๋ถ๋ถ Linter๋ Prettier๊ฐ์ ๋๊ตฌ๋ฅผ ํตํด์ ์ถฉ๋ถํ ํด๊ฒฐํ ์ ์์ด์ ์์ฒญ ๋ง์์ ์๋ฟ์ง๋ ์์์ด์. ๊ทธ๋๋ ๋น์ฐํ ๊ฒ๋ค๋ ํ๋ฒ ๋ ์ฒดํฌํด๋ณด๊ณ , ๊ณผ๊ฑฐ์๋ ์ด๋ค์ง ์ ์ ์์ด์ ์ข์์ด์. ์ฐ๋ฆฌ ๋ชจ๋ ํด๋ฆฐ ์ฝ๋๋ฅผ ์ํด ์์ผ๋ก ๊ณ์ ๋ ธ๋ ฅํด๊ฐ์.

