Intro

ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์ดˆ์ฐฝ๊ธฐ์—๋Š” System = Routine + Subroutine ์ด์—ˆ๋‹ค. Fortran, PL/1์‹œ์ ˆ์—๋Š” System = Program + SubProgram + Function ์ด์—ˆ๋‹ค.์ง€๊ธˆ์€ Function๋งŒ ๋‚จ์•˜๋‹ค. ์ฆ‰, **์–ด๋– ํ•œ ํ”„๋กœ๊ทธ๋žจ์ด๋“  ๊ธฐ๋ณธ ๋‹จ์œ„๋Š” ํ•จ์ˆ˜๋‹ค. **์ฝ”๋“œ๋ฅผ ์ฝ๋‹ค๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํŠน์ง•๋“ค์„ ๊ฐ€์ง€๋Š” ์ฝ”๋“œ๋ฅผ ์ฝ๊ฒŒ ๋œ๋‹ค.

  • ๊ธธ์ด๊ฐ€ ๊ธธ๋‹ค.
  • ์ฝ”๋“œ๊ฐ€ ์ค‘๋ณต๋˜์–ด ์žˆ๋‹ค.
  • ๋ฌธ์ž์—ด์ด ๊ดด์ƒํ•˜๋‹ค.
  • ๋‚ฏ์„ค๊ณ  ๋ชจํ˜ธํ•œ ์ž๋ฃŒ ์œ ํ˜•์ด ์žˆ๋‹ค.

์ด๋Ÿฐ ํŠน์ง•์„ ๊ฐ€์ง€๋Š” ํ•จ์ˆ˜๋Š” ์ดํ•ดํ•˜๊ธฐ ๋งค์šฐ ์–ด๋ ต๋‹ค. ์–ด๋ฏ๊ฒŒ ํ•˜๋ฉด ์ฝ๊ธฐ ์‰ฝ๊ณ  ์ดํ•ดํ•˜๊ธฐ ์‰ฌ์šด ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์„๊นŒ?

์ž‘๊ฒŒ ๋งŒ๋“ค์–ด๋ผ

์ž‘์€๊ฒŒ ์ตœ๊ณ ๋‹ค.

public static String renderPageWithSetupsAndTeardowns( PageData pageData, boolean isSuite) throws Exception {
	boolean isTestPage = pageData.hasAttribute("Test"); 
	if (isTestPage) {
		WikiPage testPage = pageData.getWikiPage(); 
		StringBuffer newPageContent = new StringBuffer(); 
		includeSetupPages(testPage, newPageContent, isSuite); 
		newPageContent.append(pageData.getContent()); 
		includeTeardownPages(testPage, newPageContent, isSuite); 
		pageData.setContent(newPageContent.toString());
	}
	return pageData.getHtml(); 
}
public static String renderPageWithSetupsAndTeardowns( PageData pageData, boolean isSuite) throws Exception { 
   if (isTestPage(pageData)) 
   	    includeSetupAndTeardownPages(pageData, isSuite); 
   return pageData.getHtml();
}

์ €์ž๋Š” ์œ„ ์ฝ”๋“œ๋„ ์ž‘๋‹ค๊ณ  ํ•œ๋‹ค. ๋˜๋„๋ก ํ•œ ํ•จ์ˆ˜๋‹น 3~5์ค„ ๋‚ด๋กœ ์ค„์ด๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•œ๋‹ค.

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

if/else/while์— ๋“ค์–ด๊ฐ€๋Š” ๋ธ”๋ก์€ ํ•œ ์ค„์ด์–ด์•ผ ํ•œ๋‹ค. ๋“ค์—ฌ์“ฐ๊ธฐ ์ˆ˜์ค€์€ 2๋‹จ์„ ๋„˜์–ด์„œ๋ฉด ์•ˆ๋œ๋‹ค.

์ด๋ ‡๊ฒŒ ๋˜๋ฉด enclosing function(๋ฐ”๊นฅ์„ ๊ฐ์‹ธ๋Š” ํ•จ์ˆ˜)์ด ์ž‘์•„์ง€๊ณ , ๋ธ”๋ก ํ˜ธ์ถœ ์•ˆ ํ•จ์ˆ˜ ์ด๋ฆ„์„ ์ž˜ ์ง“๋Š”๋‹ค๋ฉด ์ฝ”๋“œ ์ดํ•ด๊ฐ€ ์ˆ˜์›”ํ•ด์ง„๋‹ค.

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

ํ•จ์ˆ˜๋Š” ํ•œ ๊ฐ€์ง€๋ฅผ ํ•ด์•ผ ํ•œ๋‹ค. ๊ทธ ํ•œ ๊ฐ€์ง€๋ฅผ ์ž˜ ํ•ด์•ผ ํ•œ๋‹ค. ๊ทธ ํ•œ๊ฐ€์ง€๋งŒ์„ ํ•ด์•ผ ํ•œ๋‹ค.

์ง€๊ฒน๊ฒŒ ๋“ค์—ˆ์ง€๋งŒ ์–ด๋ ค์šด ๋ง์ด๋‹ค. โ€œํ•œ ๊ฐ€์ง€โ€์˜ ์ •์˜๊ฐ€ ์ƒ๋‹นํžˆ ๋ชจํ˜ธํ•˜๋‹ค.

public static String renderPageWithSetupsAndTeardowns( PageData pageData, boolean isSuite) throws Exception { 
   if (isTestPage(pageData)) 
   	    includeSetupAndTeardownPages(pageData, isSuite); 
   return pageData.getHtml();
}

์œ„ ์ฝ”๋“œ๋Š” โ€œํ•œ ๊ฐ€์ง€โ€๋งŒ ํ•œ๋‹ค๊ณ  ๋งํ•  ์ˆ˜ ์žˆ์„๊นŒ? ํ˜น์ž๋Š” 3๊ฐ€์ง€๋ฅผ ํ•œ๋‹ค๊ณ  ๋งํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

  1. ํŽ˜์ด์ง€๊ฐ€ ํ…Œ์ŠคํŠธ ํŽ˜์ด์ง€์ธ์ง€ ํŒ๋‹จํ•œ๋‹ค.
  2. ๋งž๋‹ค๋ฉด ์„ค์ • ํŽ˜์ด์ง€์™€ ํ•ด์ œ ํŽ˜์ด์ง€๋ฅผ ๋„ฃ๋Š”๋‹ค.
  3. ํŽ˜์ด์ง€๋ฅผ HTML๋กœ ๋ Œ๋”๋งํ•œ๋‹ค.

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

ํ•จ์ˆ˜๋‚ด ์„น์…˜

ํ•จ์ˆ˜๋ฅผ ์—ฌ๋Ÿฌ Section(์˜๋ฏธ๋ก ์  ๋‹จ์œ„)์œผ๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ๋‹ค๋ฉด, ๊ทธ ํ•จ์ˆ˜๋Š” ์—ฌ๋Ÿฌ์ž‘์—…์„ ํ•˜๋Š” ์…ˆ์ด๋‹ค.

์„ ์–ธ, ์ดˆ๊ธฐํ™”, ๋™์ž‘์˜ ์„ธ ๋ถ€๋ถ„์ด ํ•˜๋‚˜์˜ ํ•จ์ˆ˜ ์•ˆ์—์„œ ์ด๋ฃจ์–ด์ง€๊ณ  ์žˆ๋‹ค๋ฉด, ์—ฌ๋Ÿฌ ์ž‘์—…์„ ํ•˜๊ณ  ์žˆ๋‹ค๋Š” ๋ฐ˜์ฆ์ด๋‹ค.

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

ํ•จ์ˆ˜๊ฐ€ ํ™•์‹คํžˆ โ€œํ•œ ๊ฐ€์ง€โ€๋งŒ ํ•˜๋ ค๋ฉด, ํ•จ์ˆ˜๋‚ด ๋ชจ๋“  ๋ฌธ์žฅ์˜ ์ถ”์ƒํ™” ์ˆ˜์ค€์ด ๊ฐ™์•„์•ผ ํ•œ๋‹ค.

์•„๊นŒ ๋งํ–ˆ๋˜ function depth์™€ ์—ฐ๊ด€์ด ์žˆ๋‹ค๋Š” ๋ง์ด ์ด ๋ง์ด๋‹ค. ์‚ฌ๋žŒ์€ ์ถ”์ƒ์ ์ธ ๋‚ด์šฉ์œผ๋กœ ์‹œ์ž‘ํ•ด์„œ ๊ตฌ์ฒด์ ์ธ ๋‚ด์šฉ์„ ์ฝ๋Š” ๊ฒƒ์„ ์ž˜ํ•œ๋‹ค. ์ฝ”๋“œ ์—ญ์‹œ ์ด๋Ÿฐ์‹์œผ๋กœ ์ž‘์„ฑํ•ด์•ผ ํ•œ๋‹ค.

๋‚ด๋ ค๊ฐ€๊ธฐ ๊ทœ์น™

์ด๋Ÿฌํ•œ ์ ์—์„œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ๋•Œ๋„ ์ƒ์œ„์—๋Š” ๋†’์€ ์ˆ˜์ค€์˜ ์ถ”์ƒํ™” ์ˆ˜์ค€, ํ•˜์œ„์—๋Š” ๋‚ฎ์€ ์ˆ˜์ค€์˜ ์ถ”์ƒํ™” ์ˆ˜์ค€์ด ๋‹ด๊ธด ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ด ์ฝ๊ธฐ ์ˆ˜์›”ํ•˜๋‹ค.

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); 
	}
}

๋ฌธ์ œ๋Š” ์ด๋…€์„์ด๋‹ค. ์ด๋…€์„์„ ๋งˆ์ฃผํ•  ๋•Œ๋งˆ๋‹ค ์ž‘๊ฒŒ ๋งŒ๋“ค๊ธฐ๊ฐ€ ํž˜๋“ค์–ด์„œ ๊ณ ์ƒํ–ˆ์—ˆ๋‹ค. ๋ณธ์งˆ์ ์œผ๋กœ Switch๋ฌธ์ด ๊ฐ€์ง€๋Š” ๊ณ ์งˆ์ ์ด๋ผ ํ•  ์ˆ˜ ์žˆ๊ฒ ๋‹ค.(if/else๋„ ๋งˆ์ฐฌ๊ฐ€์ง€) ์ด๋Ÿฌํ•œ ์ ์—์„œ ์‚ฌ์‹ค ๋‹คํ˜•์„ฑ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ๊น”๋”ํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

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 SalariedEmploye(r);
			default:
				throw new InvalidEmployeeType(r.type);
		} 
	}
}

Factory๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ, ์‹ค์ œ instance๋ฅผ ๋งŒ๋“ค์–ด ๋‚ด๋ณด๋‚ธ๋‹ค. Switch๋ฌธ์€ factory๋‚ด์—์„œ๋งŒ ์‚ฌ์šฉํ•˜๋„๋ก ๊ฝ๊ฝ ์ˆจ๊น€์œผ๋กœ์„œ ๋ณด๋‹ค ๊น”๋”ํ•œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ฌผ๋ก .. ๋ถˆ๊ฐ€ํ”ผํ•œ ์ƒํ™ฉ๋„ ์žˆ๋‹ค. ใ… ใ… 

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

โ€œ์ฝ”๋“œ๋ฅผ ์ฝ์œผ๋ฉด์„œ ์ง์ž‘ํ–ˆ๋˜ ๊ธฐ๋Šฅ์„ ๊ฐ ๋ฃจํ‹ด์ด ๊ทธ๋Œ€๋กœ ์ˆ˜ํ–‰ํ•œ๋‹ค๋ฉด ๊นจ๋—ํ•œ ์ฝ”๋“œ๋ผ ๋ถˆ๋Ÿฌ๋„ ๋˜๊ฒ ๋‹คโ€ - ์›Œ๋“œ

์ด์ „ ์žฅ์—์„œ ๋Œ€๊ฐ€๋“ค์˜ Clean code์— ๋Œ€ํ•œ ์ด์•ผ๊ธฐ๋ฅผ ๋“ค์—ˆ์—ˆ๋Š”๋ฐ, ์ด ๋•Œ ๋งํ•œ โ€œ์ง์ž‘ํ–ˆ๋˜ ๊ธฐ๋Šฅโ€์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ์œ„ํ•ด ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ฒƒ์€ ์ด๋ฆ„์ด๋‹ค. ์ด ๋•Œ, ์•„๊นŒ๋งํ•œ โ€œ์ž‘๊ฒŒ ๋งŒ๋“ค์–ด๋ผโ€ ๊ทœ์น™์„ ์ ์šฉํ•œ ์ž‘์€ ํ•จ์ˆ˜๋ผ๋ฉด ๊ทธ ๊ธฐ๋Šฅ์ด ๋ช…ํ™•ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฆ„์„ ๋ถ™์ด๊ธฐ๊ฐ€ ๋” ์‰ฝ๋‹ค. ์ผ๊ด€์ ์ธ ์„œ์ˆ ํ˜• ์ด๋ฆ„(๋™์‚ฌ)๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ์ˆœ์ฐจ์ ์œผ๋กœ ์ดํ•ดํ•˜๊ธฐ๋„ ์‰ฝ๋‹ค.

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

์ด์ƒ์ ์ธ ํ•จ์ˆ˜ ์ธ์ˆ˜๋Š” 0๊ฐœ์ด๋‹ค. ์ฐจ์„ ์€ 1๊ฐœ.

Class ๋‚ด๋ถ€์— instance ๋ณ€์ˆ˜๋กœ ๋“ค๊ณ ์žˆ์ง€ ์•Š๊ณ  ์ผ์ผํžˆ ์ธ์ž๋กœ ๋„˜๊ฒจ์„œ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ์„ ๊ฒƒ์ด๋‹ค. ํ•˜์ง€๋งŒ ์ด๋ ‡๊ฒŒ ํ•  ๊ฒฝ์šฐ ๊ฐ€๋…์„ฑ์—๋Š” ์˜คํžˆ๋ ค ์ข‹์ง€ ์•Š์€๋ฐ, ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ด์œ ๊ฐ€ ์žˆ๋‹ค.

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

๊ถ๊ธˆ์ฆ: ๊ทธ๋Ÿฐ๋ฐ ๊ทธ๋Ÿผ ํด๋ž˜์Šค ๋‚ด๋ถ€์—์„œ ๊ณตํ†ต์˜ ์ƒํƒœ๊ฐ’์„ ์—ฌ๊ธฐ์„œ ๋ณ€๊ฒฝ, ์ €๊ธฐ์„œ ๋ณ€๊ฒฝํ•ด๋„ ๊ดœ์ฐฎ์„๊นŒ? ์ˆœ์ˆ˜ํ•จ์ˆ˜๊ฐ€ ๋ณด๋‹ค ๋‚ซ๋‹ค๋Š” ๋ง์€ ๋ฌด์Šจ ๋ง์ผ๊นŒ?

๋งŽ์ด ์“ฐ๋Š” ๋‹จํ•ญ(์ธ์ˆ˜ 1๊ฐœ) ๋ฐฉ์‹

  1. ์ธ์ˆ˜์— ์งˆ๋ฌธ์„ ๋˜์ง€๋Š” ๊ฒฝ์šฐ: boolean fileExists(โ€œMyFileโ€);
  2. ์ธ์ˆ˜๋ฅผ ๋ณ€ํ™˜ํ•˜์—ฌ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒฝ์šฐ: InputStream fileOpen(โ€œMyFileโ€);
  3. ์ด๋ฒคํŠธ ํ•จ์ˆ˜์ธ ๊ฒฝ์šฐ: passwordAttemptFailedNTimes(int attempts)
    • ์ด๋ฒคํŠธ ํ•จ์ˆ˜๋ผ๋Š” ์‚ฌ์‹ค์ด ์ฝ”๋“œ์— ๋ช…ํ™•ํžˆ ๋“œ๋Ÿฌ๋‚˜์•ผ ํ•œ๋‹ค.

์œ„์˜ ์„ค๋ช…ํ•œ ๊ฒฝ์šฐ๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด ๋‹จํ•ญ ํ•จ์ˆ˜๋Š” ๊ฐ€๊ธ‰์  ํ”ผํ•˜๋„๋ก ํ•œ๋‹ค.

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

์ถ”ํ•˜๋‹ค ์ถ”ํ•ด

๋Œ€๋†“๊ณ  ์ธ์ˆ˜๋กœ Bool ๊ฐ’์„ ๋ฐ›์œผ๋ฉด์„œ, โ€œ์ €๋Š” ๋‘๊ฐ€์ง€ ์ผ์„ ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹คโ€๋ฅผ ๊ด‘๊ณ ํ•˜๋Š” ๊ผด์ด๋‹ค. So Sad.. ๋ฐ˜์„ฑ.. ์ฐจ๋ผ๋ฆฌ ํ•จ์ˆ˜๋ฅผ ๋‚˜๋ˆ ๋†“๊ณ  ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์ด ์ข‹์€ ๋ฐฉ์‹์ด๋ผ ํ•œ๋‹ค.

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

๋‹จํ•ญ ๋ณด๋‹ค ์ดํ•ดํ•˜๊ธฐ ์–ด๋ ต๋‹ค.

Point ํด๋ž˜์Šค์˜ ๊ฒฝ์šฐ์—๋Š” ์ดํ•ญ ํ•จ์ˆ˜๊ฐ€ ์ ์ ˆํ•˜๋‹ค. 2๊ฐœ์˜ ์ธ์ˆ˜๊ฐ„์˜ ์ž์—ฐ์ ์ธ ์ˆœ์„œ๊ฐ€ ์žˆ์–ด์•ผํ•จ Point p = new Point(x,y); ๋ฌด์กฐ๊ฑด ๋‚˜์œ ๊ฒƒ์€ ์•„๋‹ˆ์ง€๋งŒ, ์ธ์ˆ˜๊ฐ€ 2๊ฐœ์ด๋‹ˆ ๋งŒํผ ์ดํ•ด๊ฐ€ ์–ด๋ ต๊ณ  ์œ„ํ—˜์ด ๋”ฐ๋ฅด๋ฏ€๋กœ ๊ฐ€๋Šฅํ•˜๋ฉด ๋‹จํ•ญ์œผ๋กœ ๋ฐ”๊พธ๋„๋ก ํ•˜์ž. ๊ตณ์ด ์ธ์ˆ˜ 2๊ฐœ๋ฅผ ๋ฐ›๊ธฐ๋ณด๋‹ค, ํŠน์ • Class ๋‚ด๋ถ€์— instance method๋ฅผ ๋งŒ๋“ค์–ด ๋‹จํ•ญ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ๋‹ค.

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

์‹ ์ค‘ํžˆ, ๋˜ ์‹ ์ค‘ํžˆ ๋งŒ๋“ค์–ด๋ผ.

์ดํ•ญ ํ•จ์ˆ˜๋ณด๋‹ค ์ดํ•ดํ•˜๊ธฐ๊ฐ€ ํ›จ์”ฌ ์–ด๋ ต๋‹ค. ์œ„ํ—˜๋„ 2๋ฐฐ์ด์ƒ ๋Š˜์–ด๋‚œ๋‹ค. assertEquals(message, expected, actual)์„ ์ƒ๊ฐํ•ด๋ณด๋ฉด ๋ฉˆ์นซํ•œ๋‹ค. ์ฒ˜์Œ์ด ๋ณดํ†ต expected๋ผ ์ƒ๊ฐํ–ˆ๋Š”๋ฐ, ์•Œ๊ณ ๋ณด๋‹ˆ message๋‹ค.

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

์ธ์ˆ˜๊ฐ€ 2~3๊ฐœ ํ•„์š”ํ•˜๋‹ค๋ฉด ๋…์ž์ ์ธ ํด๋ž˜์Šค ๋ณ€์ˆ˜๋กœ ์„ ์–ธํ•  ๊ฐ€๋Šฅ์„ฑ์„ ์ƒ๊ฐํ•ด๋ณด์ž.

์ด ํŒ์ด ์ œ์ผ ๋„์›€์ด ๋งŽ์ด ๋˜๋Š” ๊ฒƒ ๊ฐ™๋‹ค.

Circle makeCircle(doudle x, double y, double radius);
Circle makeCircle(Point center, double radius);

ํŠธ๋ฆญ์ด๋ผ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๊ทธ๋ ‡์ง€ ์•Š๋‹ค. ๋ฌถ์Œ์œผ๋กœ์„œ ์–ด๋– ํ•œ ๊ฐœ๋…์„ ํ‘œํ˜„ํ•˜๊ณ  ์žˆ๋‹ค.

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

String.format ๊ฐ™์€ ํ•จ์ˆ˜๋“ค์€ ์ธ์ˆ˜ ๊ฐœ์ˆ˜๊ฐ€ ๊ฐ€๋ณ€์ ์ด๋‹ค. (String์— %s ๋„ฃ๋Š” ์นœ๊ตฌ) ์ด๋Ÿฐ ๊ฒฝ์šฐ ์ธ์ˆ˜๋ฅผ List ํ˜• ์ธ์ˆ˜ํ•˜๋‚˜๋กœ ์ทจ๊ธ‰ํ•˜๊ฒŒ ๋˜๋ฉด ๊ฒฐ๊ตญ ์ดํ•ญ ํ•จ์ˆ˜๋กœ ์ทจ๊ธ‰ํ•  ์ˆ˜ ์žˆ๋‹ค. ์‹ค์ œ ์„ ์–ธ๋ถ€๋ฅผ ๋ณด๋ฉด ์ดํ•ญ ํ•จ์ˆ˜๋‹ค.

public String formay(String format, Object...args)

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

๋‹จํ•ญ ํ•จ์ˆ˜๋Š” ํ•จ์ˆ˜์™€ ์ธ์ˆ˜๊ฐ€ ๋™์‚ฌ/๋ช…์‚ฌ ์Œ์„ ์ด๋ฃจ์–ด์•ผ ํ•œ๋‹ค.

writeField(name);

ํ•จ์ˆ˜ ์ด๋ฆ„์— ํ‚ค์›Œ๋“œ(์ธ์ˆ˜ ์ด๋ฆ„)์„ ์ถ”๊ฐ€ํ•˜๋ฉด ์ธ์ˆ˜ ์ˆœ์„œ๋ฅผ ๊ธฐ์–ตํ•  ํ•„์š”๊ฐ€ ์—†์–ด์ง„๋‹ค.

assertExpectedEquialsActual(expected, actual);

๋ถ€์ˆ˜ ํšจ๊ณผ๋ฅผ ์ผ์œผํ‚ค์ง€ ๋งˆ๋ผ!

๋ถ€์ˆ˜ ํšจ๊ณผ(Side Effect)๋Š” ๋ชป๋œ ๋†ˆ. ํ•œ ๊ฐ€์ง€๋ฅผ ์•ˆํ•˜๊ณ  ๋’ค์—์„œ ๋”ด ์ง“ํ•œ๋‹ค๋Š” ๋ง์ด๋‹ค.

public class UserValidator {
	private Cryptographer cryptographer;
	public boolean checkPassword(String userName, String password) { 
		User user = UserGateway.findByName(userName);
		if (user != User.NULL) {
			String codedPhrase = user.getPhraseEncodedByPassword(); 
			String phrase = cryptographer.decrypt(codedPhrase, password); 
			if ("Valid Password".equals(phrase)) {
				Session.initialize();
				return true; 
			}
		}
		return false; 
	}
}

๊ฒ‰์œผ๋กœ ๋ณด๊ธฐ์—๋Š” ๋ฌด์Šจ ๋ฌธ์ œ๊ฐ€ ์žˆ๋Š”์ง€ ์ „ํ˜€ ๋ชจ๋ฅด๊ฒ ๋‹ค. username๊ณผ password๋ฅผ ํ™•์ธํ•˜๊ณ  ๋‘ ์ธ์ˆ˜๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๋ฉด true๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ์•„๋‹ˆ๋ฉด false๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ . ๊ทธ๋Ÿฐ๋ฐ ํ•จ์ˆ˜ ์ด๋ฆ„์„ ๋ณด๋‹ˆ๊นŒ ์ด์ƒํ•˜๋‹ค. checkPassword ํ•จ์ˆ˜ ๋‚ด์—์„œ session์„ ์ดˆ๊ธฐํ™”ํ•˜๊ณ  ์žˆ๋‹ค.

checkPassword๋ผ๋Š” ํ•˜๋‚˜์˜ ํ–‰๋™์„ ํ•˜๊ณ  ์žˆ์ง€ ์•Š๊ณ , session์„ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ๋™์ž‘๊นŒ์ง€ ํ•˜๊ณ  ์žˆ๋‹ค. ์ด๋ ‡๊ฒŒ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ฒŒ ๋˜๋ฉด, checkPassword๋ผ๋Š” ํ–‰์œ„๋Š” session์„ ์ดˆ๊ธฐํ™”ํ•ด๋„ ๊ดœ์ฐฎ์€ ๊ฒฝ์šฐ์—๋งŒ ํ˜ธ์ถœ๊ฐ€๋Šฅํ•ด์ง„๋‹ค.

์ถœ๋ ฅ ์ธ์ˆ˜

ํ”ผํ•ด๋ผ. ์ด๊ฒŒ ๋ญ์•ผ

์ธ์ˆ˜๋Š” ๋ณดํ†ต input์œผ๋กœ ์ƒ๊ฐํ•œ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์—ฌ๊ธฐ์— ์ถœ๋ ฅ์„ ๋‹ด๊ธฐ ์œ„ํ•œ ์ธ์ˆ˜๋ฅผ ๋„ฃ์–ด์ค€๋‹ค๋Š” ๊ฒƒ์€ ์šฐ๋ฆฌ์˜ ๋ณดํŽธ์  ์ƒ์‹๊ณผ ๋งž์ง€ ์•Š๋Š”๋‹ค.

๋ช…๋ น๊ณผ ์กฐํšŒ๋ฅผ ๋ถ„๋ฆฌํ•˜๋ผ!

ํ•จ์ˆ˜๋Š” โ€œ์ˆ˜ํ–‰โ€ํ•˜๊ฑฐ๋‚˜ โ€œ๋‹ตโ€ํ•˜๊ฑฐ๋‚˜ ๋‘˜ ์ค‘ ํ•˜๋‚˜๋‹ค.

์ฆ‰, ๊ฐ์ฒด ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•˜๊ฑฐ๋‚˜ ์•„๋‹ˆ๋ฉด ๊ฐ์ฒด์ •๋ณด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ฑฐ๋‚˜ ๋‘˜ ์ค‘ ํ•˜๋‚˜์ด๋‹ค.

public boolean set(String attribute, String value); // attribute๋ฅผ ์ฐพ์•„์„œ value๋กœ settingํ•ด์ค˜, setting๋˜๋ฉด true๋กœ ๋ฐ˜ํ™˜ํ•ด์ค˜
 
if(set(โ€œusernameโ€, โ€œunclebobโ€))... // ..? ์ด๊ฒŒ ๋ฌด์Šจ ๋ง์ด์•ผ

๋„๋Œ€์ฒด ๋ฌด์Šจ ๋ง์ผ๊นŒ. ์ด๊ฑด username์„ unclebob์ธ์ง€ ํ™•์ธํ•˜๋Š” ๊ฑธ๊นŒ, ์„ธํŒ…ํ•˜๋Š” ๊ฑธ๊นŒ? setAndCheckIfExist๋ผ๊ณ  ๋ณ€๊ฒฝํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ์ง€๋งŒ, ๊ทธ๊ฒƒ๋ณด๋‹ค๋Š” ์• ์ดˆ์— ๋ณ€๊ฒฝ๊ณผ ์กฐํšŒ๋ฅผ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ํ™•์‹คํ•˜๋‹ค.

if (attrivuteEdists("username")) {
    setAttribute("username", "unclebob");
}

์˜ค๋ฅ˜ ์ฝ”๋“œ๋ณด๋‹ค ์˜ˆ์™ธ๋ฅผ ์‚ฌ์šฉํ•˜๋ผ!

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

if (deletePage(page) == E_OK) {
	if (registry.deleteReference(page.name) == E_OK) {
		if (configKeys.deleteKey(page.name.makeKey()) == E_OK) {
			logger.log("page deleted");
		} else {
			logger.log("configKey not deleted");
		}
	} else {
		logger.log("deleteReference from registry failed"); 
	} 
} else {
	logger.log("delete failed"); return E_ERROR;
}

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

public void delete(Page page) {
	try {
		deletePageAndAllReferences(page);
  	} catch (Exception e) {
  		logError(e);
  	}
}
 
private void deletePageAndAllReferences(Page page) throws Exception { 
	deletePage(page);
	registry.deleteReference(page.name); 
	configKeys.deleteKey(page.name.makeKey());
}
 
private void logError(Exception e) { 
	logger.log(e.getMessage());
}

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

Error.java ์˜์กด์„ฑ ์ž์„

public enum Error { 
	OK,
	INVALID,
	NO_SUCH,
	LOCKED,
	OUT_OF_RESOURCES, 	
	WAITING_FOR_EVENT;
}

์˜ค๋ฅ˜๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ณณ๊ณณ์—์„œ ์˜ค๋ฅ˜์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด enum class๋ฅผ ์“ฐ๊ฒŒ ๋˜๋Š”๋ฐ ์ด๋Ÿฐ ํด๋ž˜์Šค๋Š” ์˜์กด์„ฑ ์ž์„์ด๋ฏ€๋กœ, ์ƒˆ ์˜ค๋ฅ˜์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ๋ณ€๊ฒฝํ•  ๋•Œ ์ฝ”์ŠคํŠธ๊ฐ€ ๋งŽ์ด ํ•„์š”ํ•˜๋‹ค. ๊ทธ๋Ÿฌ๋ฏ€๋กœ ์˜ˆ์™ธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ๋” ์•ˆ์ „ํ•˜๋‹ค. ์ฆ‰ Exception class๋ฅผ ํŒŒ์ƒํ•ด์„œ ๋งŒ๋“ค์–ด์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์‚ฌ์šฉํ•ด๋ผ.

๋ฐ˜๋ณตํ•˜์ง€ ๋งˆ๋ผ!

์ค‘๋ณต์€ ์†Œํ”„ํŠธ์›จ์–ด์—์„œ ๋ชจ๋“  ์•…์˜ ๊ทผ์›์ด๋‹ค.

๊ตฌ์กฐ์  ํ”„๋กœ๊ทธ๋ž˜๋ฐ

  1. ๋ชจ๋“  ํ•จ์ˆ˜์™€ ํ•จ์ˆ˜ ๋‚ด ๋ชจ๋“  ๋ธ”๋ก์— ์ž…๊ตฌ์™€ ์ถœ๊ตฌ๋Š” ํ•˜๋‚˜์”ฉ๋งŒ ์กด์žฌํ•ด์•ผ ํ•œ๋‹ค.
  2. ํ•จ์ˆ˜๋Š” return ๋ฌธ์ด ํ•˜๋‚˜์—ฌ์•ผ ํ•œ๋‹ค.
  3. break, continue ์•ˆ๋œ๋‹ค.
  4. goto๋Š” ์ฃฝ์–ด๋„ ์•ˆ๋œ๋‹ค.

์œ„์™€ ๊ฐ™์€ ๋ฐฉ์‹์„ ๊ตฌ์กฐ์  ํ”„๋กœ๊ทธ๋ž˜๋ฐ์ด๋ผ ํ•œ๋‹ค. Dijkstra๊ฐ€ ์ œ์ฐฝํ•œ ์›์น™์ด๋‹ค. ํ•˜์ง€๋งŒ ํ•จ์ˆ˜๊ฐ€ ์ž‘์„ ๊ฒฝ์šฐ, ์œ„์˜ ๊ทœ์น™์€ ๋ณ„๋‹ค๋ฅธ ํšจ์šฉ์ด ์—†๋‹ค. ์ž‘์„ ๊ฒฝ์šฐ์—๋Š” return, break, continue ์‚ฌ์šฉ์€ ๋ฌธ์ œ ์—†๋‹ค. ์˜คํžˆ๋ ค ๋‹จ์ผ ์ž…/์ถœ๊ตฌ ๊ทœ์น™๋ณด๋‹ค ์˜๋„ ํ‘œํ˜„์ด ์‰ฌ์›Œ์งˆ ๋•Œ๊ฐ€ ๋งŽ๋‹ค.

ํ•จ์ˆ˜๋ฅผ ์–ด๋–ป๊ฒŒ ์งœ์ฃ ?

์ฒ˜์Œ๋ถ€ํ„ฐ ํ•  ์ˆ˜ ์—†๋‹ค.

๊ธ€์ง“๊ธฐ์™€ ๋น„์Šทํ•˜๋‹ค. ์ƒ๊ฐ๋“ค์„ ๊ธฐ๋กํ•˜๊ณ , ์ฝ๊ธฐ ์ข‹๊ฒŒ ๋‹ค๋“ฌ๋Š”๋‹ค. ์ดˆ์•ˆ์€ ์„œํˆฌ๋ฅด์ง€๋งŒ ์ •๋ฆฌํ•  ์ˆ˜๋ก ์ข‹์€ ๋ฌธ์žฅ์ด ๋‚˜์˜จ๋‹ค. ์ฝ”๋“œ๋„ ๊ทธ๋ ‡๋‹ค.

๊ฒฐ๋ก 

ํ•จ์ˆ˜๋ฅผ ์ž˜ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค, ์‹œ์Šคํ…œ์ด๋ผ๋Š” ์ด์•ผ๊ธฐ๋ฅผ ํ’€์–ด๊ฐ€๋Š” ๊ฒƒ์ด ์ง„์ •ํ•œ ๋ชฉํ‘œ์ž„์„ ์žŠ์ง€๋งˆ๋ผ.

๊ทธ ๊ณผ์ •์—์„œ ํ•จ์ˆ˜๋ฅผ ์ž˜ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์€ ์ด์•ผ๊ธฐ๋ฅผ ํ’€๊ธฐ ์œ„ํ•œ ์ข‹์€ ๋ฐฉ๋ฒ•์ด๋‹ค. ๊ทธ ํ๋ฆ„์—์„œ ์ข‹์€ ์ˆ˜๋‹จ์œผ๋กœ ์ƒ๊ฐํ•˜๋Š” ๊ฒƒ์ด ๋ชฉ์ ์„ ์žŠ์ง€ ์•Š๋Š”๋ฐ ๋„์›€์ด ๋  ๊ฒƒ์ด๋‹ค.

Reference