CleanCode TIL (2022.01.28)

Henry Choยท2022๋…„ 1์›” 28์ผ
0

๋…ธ๊ฐœ๋ถ

๋ชฉ๋ก ๋ณด๊ธฐ
8/31

DAY 8

๐Ÿ”–ย ์˜ค๋Š˜ ์ฝ์€ ๋ฒ”์œ„ : 4.์ฃผ์„(68~75p)


๐Ÿค“ย ์ฑ…์—์„œ ๊ธฐ์–ตํ•˜๊ณ  ์‹ถ์€ ๋‚ด์šฉ

  • ์‹คํŒจ๋ฅผ ๋งŒํšŒํ•˜๊ธฐ ์œ„ํ•ด ์ฃผ์„์„ ์‚ฌ์šฉํ•œ๋‹ค โ†’ ์ •๋ง ์ฝ”๋“œ๋กœ ์˜๋„๋ฅผ ํ‘œํ˜„ํ•  ๋ฐฉ๋ฒ•์ด ๋” ์—†๋‚˜ ๊ณ ๋ฏผ
  • ์ฃผ์„์„ ์œ ์ง€๋ณด์ˆ˜ํ•˜๋Š”๊ฒƒ์€ ๋ถˆ๊ฐ€๋Šฅ โ†’ ์˜ค๋ž˜๋  ์ˆ˜๋ก ์ฝ”๋“œ์—์„œ ๋ฉ€์–ด์ง„๋‹ค
    MockRequest request;
    private final String HTTP_DATE_REGEXP =
    "[SMTWF][a-z]{2}\\,\\s[0-9]{2}\\s[JFMASOND][a-z]{2}\\s"+
    "[0-9]{4}\\s[0-9]{2}\\:[0-9]{2}\\:[0-9]{2}\\sGMT"; private Response response;
    private FitNesseContext context;
    private FileResponder responder;
    private Locale saveLocale;
    // Example: "Tue, 02 Apr 2003 22:18:49 GMT"
    ๋‚˜์ค‘์— ์ถ”๊ฐ€๋œ ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜๋“ค์ด ์ฃผ์„์„ ์›๋ณธ ์ฝ”๋“œ์—์„œ ๋ฉ€์–ด์ง€๊ฒŒ ํ–ˆ์„๋“ฏํ•˜๋‹ค
  • ์ฝ”๋“œ๋งŒ์ด ์ž๊ธฐ๊ฐ€ ํ•˜๋Š” ์ผ์„ ์ง„์‹ค๋˜๊ฒŒ ๋งํ•œ๋‹ค.

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

  • ํ‘œํ˜„๋ ฅ์ด ํ’๋ถ€ํ•˜๊ณ  ๊น”๋”ํ•˜๋ฉฐ ์ฃผ์„์ด ๊ฑฐ์˜ ์—†๋Š” ์ฝ”๋“œ๊ฐ€ ์ฃผ์„๋งŽ์€ ์ฝ”๋“œ๋ณด๋‹ค ํ›จ์”ฌ ์ข‹๋‹ค
  • ์ฝ”๋“œ ๋‚œ์žฅํŒ์„ ์ฃผ์„์œผ๋กœ ๋ฎ์œผ๋ ค ํ•˜์ง€๋ง๊ณ  ๋‚œ์žฅํŒ์„ ๊นจ๋—์ด ์น˜์šฐ๋Š” ๋ฐ ์‹œ๊ฐ„์„ ๋ณด๋‚ด๋ผ

์ฝ”๋“œ๋กœ ์˜๋„๋ฅผ ํ‘œํ˜„ํ•˜๋ผ!

  • ์ฝ”๋“œ๋งŒ์œผ๋กœ ์˜๋„๋ฅผ ์„ค๋ช…ํ•˜๊ธฐ ์–ด๋ ค์šด ๊ฒฝ์šฐ๋„ ์กด์žฌ
// ์ง์›์—๊ฒŒ ๋ณต์ง€ ํ˜œํƒ์„ ๋ฐ›์„ ์ž๊ฒฉ์ด ์žˆ๋Š”์ง€ ๊ฒ€์‚ฌํ•œ๋‹ค. 
if ((employee.flags & HOURLY_FLAG) &&
	(employee.age > 65))

๋ณด๋‹ค๋Š”.. ์ฃผ์„๋„ ํ•จ์ˆ˜๋ช…์œผ๋กœ ํ‘œํ˜„ํ•œ๋‹ค

if (employee.isEligibleForFullBenefits())

์ข‹์€ ์ฃผ์„

  • ๊ทธ๋Ÿผ์—๋„ ๊ธ€์ž๊ฐ’์„ ํ•˜๋Š” ์ฃผ์„๋“ค

๋ฒ•์ ์ธ ์ฃผ์„

  • ํ‘œ์ค€์„ ๋งž์ถ”๊ธฐ ์œ„ํ•ด ์†Œ์ŠคํŒŒ์ผ ์ฒซ๋จธ๋ฆฌ์— ์ €์ž‘๊ถŒ ์ •๋ณด์™€ ์†Œ์œ ๊ถŒ ์ •๋ณด
    // Copyright (C) 2003,2004,2005 by Object Mentor, Inc. All rights reserved. 
    // GNU General Public License ๋ฒ„์ „ 2 ์ด์ƒ์„ ๋”ฐ๋ฅด๋Š” ์กฐ๊ฑด์œผ๋กœ ๋ฐฐํฌํ•œ๋‹ค.

์ •๋ณด๋ฅผ ์ œ๊ณตํ•˜๋Š” ์ฃผ์„

  • ๋•Œ๋กœ๋Š” ๊ธฐ๋ณธ์ ์ธ ์ •๋ณด๋ฅผ ์ฃผ์„์œผ๋กœ ์ œ๊ณตํ•˜๋ฉด ํŽธ๋ฆฌ
    // ํ…Œ์ŠคํŠธ ์ค‘์ธ Responder ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
    protected abstract Responder responderInstance();
    ๊ทธ๋ž˜๋„ ์™ ๋งŒํ•˜๋ฉด responderBeingTested ์™€ ๊ฐ™์€ ์ด๋ฆ„์œผ๋กœ ์„ค๋ช…ํ•˜์ž

์˜๋„๋ฅผ ์„ค๋ช…ํ•˜๋Š” ์ฃผ์„

  • ๊ตฌํ˜„ ์ดํ•ด๋ฅผ ๋„˜์–ด ๊ฒฐ์ •์— ๊น”๋ฆฐ ์˜๋„๊นŒ์ง€ ์„ค๋ช…
    public int compareTo(Object o) {
    	if(o instanceof WikiPagePath) {
    		WikiPagePath p = (WikiPagePath) o;
    		String compressedName = StringUtil.join(names, "");
    		String compressedArgumentName = StringUtil.join(p.names, ""); 
    		return 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.PageA");
        assertTrue(a.compareTo(a) == 0);
        assertTrue(a.compareTo(b) != 0);
        assertTrue(ab.compareTo(ab) == 0);
        assertTrue(a.compareTo(b) == -1);
        assertTrue(aa.compareTo(ab) == -1);
        assertTrue(ba.compareTo(bb) == -1);
        assertTrue(b.compareTo(a) == 1);
        assertTrue(ab.compareTo(aa) == 1);
        assertTrue(bb.compareTo(ba) == 1);
        // a == a // a != b // ab == ab // a < b
        // aa < ab // ba < bb // b > a // ab > aa // bb > ba
    }

๊ฒฐ๊ณผ๋ฅผ ๊ฒฝ๊ณ ํ•˜๋Š” ์ฃผ์„

  • ์˜ค๋ž˜๊ฑธ๋ฆฌ๋ฏ€๋กœ disable ํ•ด์•ผํ•˜๋Š” ํ…Œ์ŠคํŠธ์ฝ”๋“œ๋ฅผ ๊ฒฝ๊ณ 
// ์—ฌ์œ  ์‹œ๊ฐ„์ด ์ถฉ๋ถ„ํ•˜์ง€ ์•Š๋‹ค๋ฉด ์‹คํ–‰ํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค.
public void _testWithReallyBigFile() {
    writeLinesToFile(10000000);
    response.setBody(testFile);
    response.readyToSend(this);
    String responseString = output.toString();
    assertSubString("Content-Length: 1000000000", responseString);
    assertTrue(bytesSent > 1000000000);
}

JUnit4 ์ดํ›„๋กœ๋Š”@Ignore ์†์„ฑ์„ ์ด์šฉํ•ด ํ…Œ์ŠคํŠธ๋ฅผ ๋Œ์ˆ˜๋„ ์žˆ์Œ

@Ignore("์‹คํ–‰์ด ๋„ˆ๋ฌด ์˜ค๋ž˜ ๊ฑธ๋ฆฐ๋‹ค.")
...

ํ”„๋กœ๊ทธ๋žจ ํšจ์œจ ๋†’์ธ๋‹ค๊ณ  ์ •์  ์ดˆ๊ธฐํ™” ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ๋ป” ํ•˜๋‹ค๊ฐ€ ์ฃผ์„์„ ํ†ตํ•ด ์‹ค์ˆ˜๋ฅผ ๋ฉดํ•จ

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-MdM ํ˜„์žฌ ํ•„์š”ํ•˜์ง€ ์•Š๋‹ค.
// ์ฒดํฌ์•„์›ƒ ๋ชจ๋ธ์„ ๋„์ž…ํ•˜๋ฉด ํ•จ์ˆ˜๊ฐ€ ํ•„์š” ์—†๋‹ค.
protected VersionInfo makeVersion() throws Exception {
	return null; 
}
  • ์ฃผ๊ธฐ์ ์œผ๋กœ ์ ๊ฒ€ ํ•ด 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 ์—ญ์‹œ ๋…์ž๋ฅผ ์˜ค๋„ํ•˜๊ฑฐ๋‚˜ ์ž˜๋ชป ์œ„์น˜ํ•˜๊ฑฐ๋‚˜ ๊ทธ๋ฆ‡๋œ ์ •๋ณด ์ „๋‹ฌํ•˜์ง€์•Š๋„๋ก ์ฃผ์˜

๐Ÿค”ย ๋– ์˜ค๋ฅด๋Š” ์ƒ๊ฐ

  • ์ •~๋ง ํ•„์š”ํ•œ ๊ฒฝ์šฐ๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด ์ฃผ์„์€ ์ตœ๋Œ€ํ•œ ์“ฐ์ง€ ๋ง์•„์•ผ ๊ฒ ๋‹ค

๐Ÿ”Žย ์งˆ๋ฌธ

  • ์ •์  ์ดˆ๊ธฐํ™” ํ•จ์ˆ˜? ์ธ์Šคํ„ด์Šค๋ฅผ ๋…๋ฆฝ์ ์œผ๋กœ ์ƒ์„ฑ?

๐Ÿ“ย ์†Œ๊ฐ 3์ค„ ์š”์•ฝ

  • ์ธ์ˆ˜๋‚˜ ๋ฐ˜ํ™˜๊ฐ’์ด ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋‚˜ ๋ณ€๊ฒฝํ•˜์ง€ ๋ชปํ•˜๋Š” ์ฝ”๋“œ์— ์†ํ•œ๋‹ค๋ฉด ์ฃผ์„์„ ์ถ”๊ฐ€
  • ์˜ค๋ž˜๊ฑธ๋ฆฌ๋Š” ์ฝ”๋“œ๋‚˜ ์˜ˆ๊ธฐ์น˜ ๋ชปํ•œ ๊ฒฐ๊ณผ๋ฅผ ์ฃผ๋Š” ์ฝ”๋“œ์—๋Š” ๊ฒฝ๊ณ ์˜ ์ฃผ์„์„ ์ถ”๊ฐ€
  • TODO์ฃผ์„์€ ์จ๋„ ์ข‹์ง€๋งŒ ์ฃผ๊ธฐ์ ์œผ๋กœ ์ •๋ฆฌ ํ•˜์ž
profile
Full stack tech visionary

0๊ฐœ์˜ ๋Œ“๊ธ€