CleanCode TIL (2022.01.26)

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

๋…ธ๊ฐœ๋ถ

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

DAY 6

๐Ÿ”–ย ์˜ค๋Š˜ ์ฝ์€ ๋ฒ”์œ„ : 3. ํ•จ์ˆ˜ (40~54p)


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

  • ํ•จ์ˆ˜๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ ๋‹จ์œ„

๋ธ”๋ก๊ณผ ๋“ค์—ฌ์“ฐ๊ธฐ

  • if๋ฌธ/else๋ฌธ/while๋ฌธ ๋“ฑ์— ๋“ค์–ด๊ฐ€๋Š” ๋ธ”๋ก์€ ํ•œ์ค„์ด์–ด์•ผ ํ•œ๋‹ค.
  • ํ•จ์ˆ˜์—์„œ ๋“ค์—ฌ์“ฐ๊ธฐ ์ˆ˜์ค€์€ 1๋‹จ์ด๋‚˜ 2๋‹จ์„ ๋„˜์–ด์„œ๋ฉด ์•ˆ๋œ๋‹ค. 1๋‹จ์—์„œ ๋ฐ”๋กœ ํ•จ์ˆ˜ ํ˜ธ์ถœ
    public static String renderPageWithSetupsAndTeardowns(
    	PageData pageData, boolean isSuite) throws Exception {
    	if (isTestPage(pageData))
    		includeSetupAndTeardownPages(pageData, isSuite); 
    	return pageData.getHtml();
    }

ํ•œ ๊ฐ€์ง€๋งŒ ํ•ด๋ผ!

  • ํ•œ๊ฐ€์ง€: ์ง€์ •๋œ ํ•จ์ˆ˜ ์ด๋ฆ„ ์•„๋ž˜์—์„œ ์ถ”์ƒํ™” ์ˆ˜์ค€์ด ํ•˜๋‚˜์ธ ๋‹จ๊ณ„๋งŒ ์ˆ˜ํ–‰
  • ์˜๋ฏธ ์žˆ๋Š” ์ด๋ฆ„์œผ๋กœ ๋‹ค๋ฅธ ํ•จ์ˆ˜๋กœ ๋ถ„๊ฐœ๋  ์ˆ˜ ์žˆ๋‹ค๋ฉด ๊ทธ ํ•จ์ˆ˜๋Š” ์—ฌ๋Ÿฌ ์ž‘์—…์„ ํ•˜๊ณ  ์žˆ๋Š” ๊ฒƒ

ํ•จ์ˆ˜ ๋‹น ์ถ”์ƒํ™” ์ˆ˜์ค€์€ ํ•˜๋‚˜๋กœ

  • ํ•œ ๊ฐ€์ง€ ์ž‘์—…๋งŒ ํ•˜๋ ค๋ฉด ํ•จ์ˆ˜ ๋‚ด ๋ชจ๋“  ๋ฌธ์žฅ์˜ ์ถ”์ƒํ™” ์ˆ˜์ค€์ด ๋™์ผํ•ด์•ผํ•œ๋‹ค

์œ„์—์„œ ์•„๋ž˜๋กœ ์ฝ”๋“œ ์ฝ๊ธฐ: ๋‚ด๋ ค๊ฐ€๊ธฐ ๊ทœ์น™

  • ์œ„์—์„œ ์•„๋ž˜๋กœ ์ด์•ผ๊ธฐ์ฒ˜๋Ÿผ ์ฝ”๋“œ๋ฅผ ์ฝ์œผ๋ฉด ํ•จ์ˆ˜ ์ถ”์ƒํ™” ์ˆ˜์ค€์ด ํ•œ๋ฒˆ์— ํ•œ ๋‹จ๊ณ„์”ฉ ๋‚ฎ์•„์ ธ์•ผํ•œ๋‹ค.
    TO ์„ค์ • ํŽ˜์ด์ง€์™€ ํ•ด์ œ ํŽ˜์ด์ง€๋ฅผ ํฌํ•จํ•˜๋ ค๋ฉด, ์„ค์ • ํŽ˜์ด์ง€๋ฅผ ํฌํ•จํ•˜๊ณ , ํ…Œ์ŠคํŠธ ํŽ˜์ด์ง€ ๋‚ด์šฉ์„ ํฌํ•จํ•˜๊ณ , ํ•ด์ œ ํŽ˜์ด์ง€๋ฅผ ํฌํ•จํ•œ๋‹ค.
    	TO ์„ค์ • ํŽ˜์ด์ง€๋ฅผ ํฌํ•จํ•˜๋ ค๋ฉด, ์ŠˆํŠธ์ด๋ฉด ์ŠˆํŠธ ์„ค์ • ํŽ˜์ด์ง€๋ฅผ ํฌํ•จํ•œ ํ›„ ์ผ๋ฐ˜ ์„ค์ • ํŽ˜์ด์ง€๋ฅผ ํฌํ•จํ•œ๋‹ค.
    	TO ์ŠˆํŠธ ์„ค์ • ํŽ˜์ด์ง€๋ฅผ ํฌํ•จํ•˜๋ ค๋ฉด, ๋ถ€๋ชจ ๊ณ„์ธต์—์„œ โ€œSuiteSetUpโ€ ํŽ˜์ด์ง€๋ฅผ ์ฐพ ์•„ include ๋ฌธ๊ณผ ํŽ˜์ด์ง€ ๊ฒฝ๋กœ๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.
    	TO ๋ถ€๋ชจ ๊ณ„์ธต์„ ๊ฒ€์ƒ‰ํ•˜๋ ค๋ฉด, ......

Switch๋ฌธ

  • Switch๋Š” N ๊ฐ€์ง€๋ฅผ ์ฒ˜๋ฆฌ โ†’ ์ €์ฐจ์› ํด๋ž˜์Šค์— ์ˆจ๊ธฐ๊ณ  ๋ฐ˜๋ณตํ•˜์ง€ ์•Š๊ธฐ

    ๋ฌธ์ œ

    // ์ž˜๋ชป๋œ switch ์‚ฌ์šฉ
    public Money calculatePay(Employee e) 
    throws InvalidEmployeeType {
    	switch (e.type) { 
    		case COMMISSIONED:
    			return calculateCommissionedPay(e); 
    		case HOURLY:
    			return calculateHourlyPay(e);
    		case SALARIED:
    			return calculateSalariedPay(e); 
    		default:
    			throw new InvalidEmployeeType(e.type); 
    	}
    }
    1. ํ•จ์ˆ˜๊ฐ€ ๊ธธ๋‹ค

    2. ํ•œ๊ฐ€์ง€ ์ž‘์—…๋งŒ ์ˆ˜ํ–‰ํ•˜์ง€๋ฅผ ์•Š๋Š”๋‹ค

    3. SingleResponsibilityPrinciple์„ ์œ„๋ฐ˜ (์ฝ”๋“œ๋ฅผ ๋ณ€๊ฒฝํ•  ๊ฐ€๋Šฅ์„ฑ ์กด์žฌ)

    4. OpenClosedPrinciple ์œ„๋ฐ˜ (์ƒˆ ์ง์› ์œ ํ˜• ์ถ”๊ฐ€์‹œ๋งˆ๋‹ค ์ฝ”๋“œ ๋ณ€๊ฒฝํ•„์š”)

    5. ๋™์ผ ๊ตฌ์กฐ์˜ ํ•จ์ˆ˜๊ฐ€ ๋ฌดํ•œ์ • ์กด์žฌ

      ```java
      isPayday(Employee e, Date date);
      deliverPay(Employee e, Money pay);
      ```

      ํ•ด๊ฒฐ

      public abstract class Employee {
          public abstract boolean isPayday();
          public abstract Money calculatePay();
          public abstract void deliverPay(Money pay);
      }
      -----------------
      public interface EmployeeFactory {
          public Employee makeEmployee(EmployeeRecord r) throws InvalidEmployeeType; 
      }
      -----------------
      public class EmployeeFactoryImpl implements EmployeeFactory {
          public Employee makeEmployee(EmployeeRecord r) throws InvalidEmployeeType {
              switch (r.type) {
                  case COMMISSIONED:
                      return new CommissionedEmployee(r) ;
                  case HOURLY:
                      return new HourlyEmployee(r);
                  case SALARIED:
                      return new SalariedEmployee(r); default:
                      throw new InvalidEmployeeType(r.type); 
              }
          } 
      }

      switch ๋ฌธ์„ Abstract factory์— ์ˆจ๊ธด๋‹ค

      factory๋Š” switch ํ†ตํ•ด ์ ์ ˆํ•œ Employee ํŒŒ์ƒ ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ

      calculatePay, isPayday, deliverPay ๊ฐ™์€ ํ•จ์ˆ˜๋Š” Employee ์ธํ„ฐํŽ˜์ด์Šค ๊ฑฐ์ณ ํ˜ธ์ถœ

      โ†’ ๋‹คํ˜•์„ฑ์œผ๋กœ ์‹ค์ œ ํŒŒ์ƒ ํด๋ž˜์Šค ํ•จ์ˆ˜ ์‹คํ–‰

์„œ์ˆ ์ ์ธ ์ด๋ฆ„์„ ์‚ฌ์šฉํ•˜๋ผ!

  • ์ด๋ฆ„์ด ๊ธธ์–ด๋„ ๊ดœ์ฐฎ๋‹ค. ๊ธด ์ด๋ฆ„์ด ๊ธด ์ฃผ์„๋ณด๋‹ค ์ข‹๋‹ค.
  • ๋ชจ๋“ˆ ๋‚ด์—์„œ ํ•จ์ˆ˜ ์ด๋ฆ„์€ ๊ฐ™์€ ๋ฌธ๊ตฌ, ๋ช…์‚ฌ, ๋™์‚ฌ๋ฅผ ์‚ฌ์šฉ
    includeSetupAndTeardownPages
    includeSetupPages
    includeSuiteSetupPage
    includeSetupPage

ํ•จ์ˆ˜ ์ธ์ˆ˜

  • ์ด์ƒ์ ์ธ ์ธ์ˆ˜ ๊ฐœ์ˆ˜๋Š” 0๊ฐœ
  • 3๊ฐœ๋Š” ๊ฐ€๋Šฅํ•œ ํ”ผํ•œ๋‹ค
  • 4๊ฐœ ์ด์ƒ์€ ํŠน๋ณ„ํ•œ ์ด์œ  ๊ฐ€ ์žˆ์–ด๋„ ์‚ฌ์šฉ โŒ
  • ์ธ์ˆ˜๋Š” ์–ด๋ ต๋‹ค. ํ•จ์ˆ˜์™€ ์ธ์ˆ˜์‚ฌ์ด์— ์ถ”์ƒํ™” ์ˆ˜์ค€์ด ๋‹ค๋ฅด๋‹ค.
  • ์ธ์ˆ˜๋Š” ํ˜„ ์‹œ์ ์—์„œ ๋ณ„๋กœ ์ค‘์š”ํ•˜์ง€ ์•Š์€ ์„ธ๋ถ€์‚ฌํ•ญ๋„ ์•Œ์•„์•ผํ•˜๊ฒŒ๋งŒ๋“ ๋‹ค.
  • ํ…Œ์ŠคํŠธ ๊ด€์ ์—์„œ๋„ ์–ด๋ ต๋‹ค
  • ์ถœ๋ ฅ ์ธ์ˆ˜๋Š” ์ž…๋ ฅ ์ธ์ˆ˜๋ณด๋‹ค ๋” ์ดํ•ดํ•˜๊ธฐ ์–ด๋ ต๋‹ค

๋งŽ์ด ์“ฐ๋Š” ๋‹จํ•ญ ํ˜•์‹

  • ์ธ์ˆ˜์— ์งˆ๋ฌธ์„ ๋˜์ง€๋Š” ๊ฒฝ์šฐ
    boolean fileExists("MyFile")
  • ์ธ์ˆ˜๋ฅผ ๋ญ”๊ฐ€๋กœ ๋ณ€ํ™˜ํ•ด ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒฝ์šฐ
    InputStream fileOpen("MyFile")
  • ์ด๋ฒคํŠธ: ์ž…๋ ฅ ์ธ์ˆ˜๋กœ ์‹œ์Šคํ…œ ์ƒํƒœ๋ฅผ ๋ฐ”๊ฟˆ
    passwordAttemptFailedNtimes(int attempts)

ํ”Œ๋ž˜๊ทธ ์ธ์ˆ˜

  • ํ”Œ๋ž˜๊ทธ ์ธ์ˆ˜๋Š” ์ถ”ํ•˜๋‹ค. ํ•จ์ˆ˜๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐ€์ง€๋ฅผ ์ฒ˜๋ฆฌํ•œ๋‹ค๊ณ  ๋Œ€๋†“๊ณ  ๊ณตํ‘œํ•˜๋Š” ๊ฒƒ โ†’ ๋‚˜๋ˆ ์•ผ ๋งˆ๋•…

์ดํ•ญ ํ•จ์ˆ˜

  • ์ธ์ˆ˜๊ฐ€ 2๊ฐœ๋ฉด ์ดํ•ด ์–ด๋ ต๋‹ค โ†’ ์ผ๋ถ€ ๋ฌด์‹œํ•œ๋‹ค โ†’ ์˜ค๋ฅ˜ ๋ฐœ์ƒ eg) assertEquals(expected, actual) โ†’ ์ˆœ์„œ ์™ธ์šฐ์ง€ ์•Š์œผ๋ฉด ํ—ท๊ฐˆ๋ฆฐ๋‹ค

์‚ผํ•ญ ํ•จ์ˆ˜

  • ์ˆœ์„œ, ์ฃผ์ถค, ๋ฌด์‹œ โ†’ ๋ฌธ์ œ
    assertEquals(message, expected, actual)

์ธ์ˆ˜ ๊ฐ์ฒด

  • ์ธ์ˆ˜๊ฐ€ 2~3๊ฐœ ํ•„์š”ํ•˜๋‹ค๋ฉด ์ผ๋ถ€๋ฅผ ๋…์ž์ ์ธ ํด๋ž˜์Šค ๋ณ€์ˆ˜๋กœ ์„ ์–ต โ†’ ํ•˜๋‚˜์˜ ๊ฐœ๋…์„ ํ‘œํ˜„
Circle makeCircle(double x, double y, double radius);
Circle makeCircle(Point center, double radius);

์ธ์ˆ˜ ๋ชฉ๋ก

  • ๊ฐ€๋ณ€ ์ธ์ˆ˜๋ฅผ List ํ˜• ์ธ์ˆ˜ ํ•˜๋‚˜๋กœ ์ทจ๊ธ‰
String.format("%s worked %.2f" hours.", name, hours);
public String format(String format, Object... args)
void monad(Integer... args);
void dyad(String name, Integer... args);
void triad(String name, int count, Integer... args);

๋™์‚ฌ์™€ ํ‚ค์›Œ๋“œ

  • ๋‹จํ•ญ ํ•จ์ˆ˜๋Š” ์ธ์ˆ˜๊ฐ€ ๋™์‚ฌ/๋ช…์‚ฌ ์Œ์„ ์ด๋ค„์•ผํ•œ๋‹ค. writeField(name)
  • ํ‚ค์›Œ๋“œ์ถ”๊ฐ€ assertEquals < assertExpectedEqualsActual(expected, actual)

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

  • ๋‚ด์šฉ์ด ์กฐ๊ธˆ ์”ฉ ์–ด๋ ค์›Œ์ ธ ๊ฐ„๋‹ค.
  • ๊นŠ์€ ์ดํ•ด๋ฅผ ์œ„ํ•ด์„œ๋Š” ํด๋ž˜์Šค์— ๋Œ€ํ•œ ๊ณต๋ถ€์™€ ์‹ค์Šต์ด ํ•„์š”ํ•˜๊ฒ ๋‹ค.

๐Ÿ”Žย ์งˆ๋ฌธ

  • void includeSetupPageInto(StringBuffer pageText)๋Š” ํ”ผํ•œ๋‹ค. ๋ณ€ํ™˜ ํ•จ์ˆ˜์—์„œ ์ถœ๋ ฅ ์ธ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ˜ผ๋ž€์„ ์ผ์œผํ‚จ๋‹ค?

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

  • ํ•จ์ˆ˜์—์„œ ๋“ค์—ฌ์“ฐ๊ธฐ ์ˆ˜์ค€์€ 1๋‹จ์ด๋‚˜ 2๋‹จ์„ ๋„˜์–ด์„œ๋ฉด ์•ˆ๋œ๋‹ค.
  • ํ•œ๊ฐ€์ง€(์ง€์ •๋œ ํ•จ์ˆ˜ ์ด๋ฆ„ ์•„๋ž˜์—์„œ ์ถ”์ƒํ™” ์ˆ˜์ค€์ด ํ•˜๋‚˜์ธ ๋‹จ๊ณ„๋งŒ ์ˆ˜ํ–‰) ๋งŒ ํ•ด๋ผ
  • ํ•จ์ˆ˜ ์ธ์ˆ˜๋Š” ์ ์„ ์ˆ˜๋ก ์ข‹๋‹ค.
profile
Full stack tech visionary

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