ํจ์(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();
}
์ ์ฝ๋๋ ๊ธธ๋ค. ๋๋๋ก ํ ํจ์๋น 3~5์ค ์ด๋ด๋ก ์ค์ด๋ ๊ฒ์ ๊ถ์ฅํ๋ค
public static String renderPageWithSetupsAndTeardowns( PageData pageData, boolean isSuite) throws Exception {
if (isTestPage(pageData))
includeSetupAndTeardownPages(pageData, isSuite);
return pageData.getHtml();
}
๋ธ๋ก๊ณผ ๋ค์ฌ์ฐ๊ธฐ
์ค์ฒฉ๊ตฌ์กฐ(if/else, while๋ฌธ ๋ฑ)์ ๋ค์ด๊ฐ๋ ๋ธ๋ก์ ํ ์ค์ด์ด์ผ ํ๋ค. ๊ฐ ํจ์ ๋ณ ๋ค์ฌ์ฐ๊ธฐ ์์ค์ด 2๋จ์ ๋์ด์์ง ์๊ณ , ๊ฐ ํจ์๊ฐ ๋ช ๋ฐฑํ๋ค๋ฉด ํจ์๋ ๋์ฑ ์ฝ๊ณ ์ดํดํ๊ธฐ ์ฌ์์ง๋ค.
ํ ๊ฐ์ง๋ง ํด๋ผ
ํจ์๋ ํ๊ฐ์ง๋ฅผ ํด์ผ ํ๋ค. ๊ทธ ํ๊ฐ์ง๋ฅผ ์ ํด์ผ ํ๋ค. ๊ทธ ํ๊ฐ์ง๋ง์ ํด์ผ ํ๋ค. ์ง์ ๋ ํจ์ ์ด๋ฆ ์๋์์ ์ถ์ํ ์์ค์ด ํ๋์ธ ๋จ๊ณ๋ง ์ํํ๋ค๋ฉด ๊ทธ ํจ์๋ ํ ๊ฐ์ง ์์ ๋ง ํ๋ ๊ฒ์ด๋ค.
ํจ์ ๋ด ์น์
ํจ์๋ฅผ ์ฌ๋ฌ ์น์ (์ ์ธ, ์ด๊ธฐํ ๋ฑ๋ฑ)์ผ๋ก ๋๋ ์ ์๋ค๋ฉด ๊ทธ ํจ์๋ ์ฌ๋ฌ์์ ์ ํ๋ ์ ์ด๋ค.
ํจ์ ๋น ์ถ์ํ ์์ค์ ํ๋๋ก ํ๊ธฐ
ํจ์๊ฐ โํ๊ฐ์งโ ์์ ๋ง ํ๋ ค๋ฉด ํจ์ ๋ด ๋ชจ๋ ๋ฌธ์ฅ์ ์ถ์ํ ์์ค์ด ๋์ผํด์ผ ๋๋ค. ๋ง์ฝ ํ ํจ์ ๋ด์ ์ถ์ํ ์์ค์ด ์์ด๊ฒ ๋๋ค๋ฉด ์ฝ๋ ์ฌ๋์ด ํท๊ฐ๋ฆฐ๋ค.
์์์ ์๋๋ก ์ฝ๋ ์ฝ๊ธฐ:๋ด๋ ค๊ฐ๊ธฐ ๊ท์น
์ฝ๋๋ ์์์ ์๋๋ก ์ด์ผ๊ธฐ์ฒ๋ผ ์ฝํ์ผ ์ข๋ค. ํจ์ ์ถ์ํ ๋ถ๋ถ์ด ํ๋ฒ์ ํ๋จ๊ณ์ฉ ๋ฎ์์ง๋ ๊ฒ์ด ๊ฐ์ฅ ์ด์์ ์ด๋ค.(๋ด๋ ค๊ฐ๊ธฐ ๊ท์น)
Switch๋ฌธ
Bad Example
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);
}
}
- ํจ์๊ฐ ๊ธธ๋ค. (์ ์ง์ ์ ํ์ ์ถ๊ฐํ๋ฉด ๋ ๊ธธ์ด์ง๋ค.)
ํ ๊ฐ์ง
์์ ๋ง ์ํํ์ง ์๋๋ค.- SRP(Single Responsibility Principle)๋ฅผ ์๋ฐํ๋ค. (์ฝ๋๋ฅผ ๋ณ๊ฒฝํ ์ด์ ๊ฐ ์ฌ๋ฟ์ด๊ธฐ ๋๋ฌธ์ด๋ค.)
- OCP(Open Closed Principle)๋ฅผ ์๋ฐํ๋ค.(์ ์ง์ ์ ํ์ ์ถ๊ฐํ ๋๋ง๋ค ์ฝ๋๋ฅผ ๋ณ๊ฒฝํ๊ธฐ ๋๋ฌธ์ด๋ค.)
Good Example
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);
}
}
}
switch๋ฌธ์ ์๊ฒ ๋ง๋ค๊ธฐ ์ด๋ ต์ง๋ง(if/else์ ์ฐ์ ๋ ๋ง์ฐฌ๊ฐ์ง!), ๋คํ์ฑ์ ์ด์ฉํ์ฌ switch๋ฌธ์ abstract factory์ ์จ๊ฒจ ๋คํ์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ์ฝ๋ ์์์๋ง switch๋ฅผ ์ฌ์ฉํ๋๋ก ํ๋ค.
์์ ์ ์ธ ์ด๋ฆ์ ์ฌ์ฉํ๊ธฐ
์ด๋ฆ์ด ๊ธธ์ด๋ ๊ด์ฐฎ๋ค. ๊ฒ๋จน์ ํ์์๋ค. ๊ธธ๊ณ ์์ ์ ์ธ ์ด๋ฆ์ด ์งง๊ณ ์ด๋ ค์ด ์ด๋ฆ๋ณด๋ค ์ข๋ค.
ํจ์ ์ธ์
ํจ์์์ ์ด์์ ์ธ ์ธ์ ๊ฐ์๋ 0๊ฐ(๋ฌดํญ). ์ธ์๋ ์ฝ๋ ์ดํด์ ๋ฐฉํด๊ฐ ๋๋ ์์์ด๋ฏ๋ก ์ต์ ์ 0๊ฐ์ด๊ณ , ์ฐจ์ ์ 1๊ฐ๋ฟ์ธ ๊ฒฝ์ฐ์ด๋ค. ์ถ๋ ฅ์ธ์(ํจ์์ ๋ฐํ ๊ฐ์ด ์๋ ์ ๋ ฅ ์ธ์๋ก ๊ฒฐ๊ณผ๋ฅผ ๋ฐ๋ ๊ฒฝ์ฐ)๋ ์ดํดํ๊ธฐ ์ด๋ ค์ฐ๋ฏ๋ก ์ ๋งํ๋ฉด ์ฐ์ง ์๋ ๊ฒ์ด ์ข๊ฒ ๋ค.
๋จํญ ํ์
- ์ธ์์ ์ง๋ฌธ์ ๋์ง๋ ๊ฒฝ์ฐ :
boolean fileExists(โMyFileโ);
- ์ธ์๋ฅผ ๋ญ๊ฐ๋ก ๋ณํํด ๊ฒฐ๊ณผ๋ฅผ ๋ณํํ๋ ๊ฒฝ์ฐ :
InputStream fileOpen("MyFile");
- ์ด๋ฒคํธ ํจ์์ผ ๊ฒฝ์ฐ (์ด ๊ฒฝ์ฐ์๋ ์ด๋ฒคํธ๋ผ๋ ์ฌ์ค์ด ์ฝ๋์ ๋ช ํํ๊ฒ ๋๋ฌ๋์ผ ํ๋ค.)
ํ๋๊ทธ ์ธ์
ํ๋๊ทธ ์ธ์๋ ์ถํ๋ค. ์ฐ์ง๋ง๋ผ. bool ๊ฐ์ ๋๊ธฐ๋ ๊ฒ ์์ฒด๊ฐ ๊ทธ ํจ์๋ ํ๊บผ๋ฒ์ ์ฌ๋ฌ๊ฐ์ง ์ผ์ ์ฒ๋ฆฌํ๋ค๊ณ ๊ณตํํ๋ ๊ฒ๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ค.
์ดํญ ํจ์
๋จํญ ํจ์๋ณด๋ค ์ดํดํ๊ธฐ๊ฐ ์ด๋ ต๋ค. Point ํด๋์ค์ ๊ฒฝ์ฐ์๋ ์ดํญ ํจ์๊ฐ ์ ์ ํ๋ค. 2๊ฐ์ ์ธ์๊ฐ์ ์์ฐ์ ์ธ ์์๊ฐ ์์ด์ผํจ ๋ฌด์กฐ๊ฑด ๋์ ๊ฒ์ ์๋์ง๋ง, ์ธ์๊ฐ 2๊ฐ์ด๋ ๋งํผ ์ดํด๊ฐ ์ด๋ ต๊ณ ์ํ์ด ๋ฐ๋ฅด๋ฏ๋ก ๊ฐ๋ฅํ๋ฉด ๋จํญ์ผ๋ก ๋ฐ๊พธ๋๋ก
- ์์ฐ์ค๋ฌ์ด ์ดํด :
assertEquals(expected, actual)
,Point p = new Point(x,y);
์ผํญ ํจ์
์ดํดํ๊ธฐ ํจ์ฌ ์ด๋ ค์ฐ๋ฏ๋ก ์ต๋ํ ์์ ํ์. ์ผํญ ํจ์๋ฅผ ๋ง๋ค ๋๋ ์ ์คํ ๊ณ ๋ คํ๋ผ.
์ธ์ ๊ฐ์ฒด
๊ฐ๋ ์ ํํํ๊ธฐ.
Circle makeCircle(double x, double y, double radius); // bad
Circle makeCircle(Point center, double radius); // good
์ธ์ ๋ชฉ๋ก
๋๋ก๋ String.format๊ฐ์ ํจ์๋ค์ฒ๋ผ ์ธ์ ๊ฐ์๊ฐ ๊ฐ๋ณ์ ์ธ ํจ์๋ ํ์ํ๋ค. String.format์ ์ธ์๋ Listํ ์ธ์์ด๊ธฐ ๋๋ฌธ์ ์ดํญํจ์๋ผ๊ณ ํ ์ ์๋ค.
๋์ฌ๋ ํค์๋
๋จํญ ํจ์๋ ํจ์์ ์ธ์๊ฐ ๋์ฌ/๋ช ์ฌ ์์ ์ด๋ค์ผํ๋ค.
write(name); // bad
writeField(name); // good
ํจ์์ด๋ฆ์ ํค์๋(์ธ์ ์ด๋ฆ)์ ์ถ๊ฐํ๋ฉด ์ธ์ ์์๋ฅผ ๊ธฐ์ตํ ํ์๊ฐ ์์ด์ง๋ค.
assertEquals(expected, actual);
assertExpectedEqualsActual(expected, actual);
๋ถ์ ํจ๊ณผ๋ฅผ ์ผ์ผํค์ง ๋ง๊ธฐ
Bad Example
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;
}
}
๋น๋ฐ๋ฒํธ๋ฅผ ํ์ธํ๋ Method์ Session ์ด๊ธฐํํ๋ ํฌํจ๋์ด์๋ค. ํ Method์ ๋๊ฐ์ง ๊ธฐ๋ฅ์ ํ๊ณ ์๋ค. ์ข์ง ๋ชปํ ํจ์์ด๋ค.
์ถ๋ ฅ์ธ์
์ผ๋ฐ์ ์ผ๋ก ์ถ๋ ฅ ์ธ์๋ ํผํด์ผ ํ๋ค. ํจ์์์ ์ํ๋ฅผ ๋ณ๊ฒฝํด์ผ ํ๋ค๋ฉด ํจ์๊ฐ ์ํ ๊ฐ์ฒด ์ํ๋ฅผ ๋ณ๊ฒฝํ๋ ๋ฐฉ์์ ํํ๋ผ.
๋ช ๋ น๊ณผ ์กฐํ๋ฅผ ๋ถ๋ฆฌํ๋ผ
public boolean set(String attribute, String value);
: ๋๊ฐ์ง ๊ธฐ๋ฅ์ ํ๊ณ ์๋ค. ์ค์ ํ๋ ๊ฒ๊ณผ ์ค์ ์ด ์ฑ๊ณตํ๋์ง ์คํจํ๋์ง.
if(set(โusernameโ, โunclebobโ))...
: ์ด์ํ ํจ์์ ๋ชจ์ต์ ๋ณผ ์ ์๋ค.
์ค๋ฅ ์ฝ๋๋ณด๋ค ์์ธ๋ฅผ ์ฌ์ฉํ๋ผ.
์ฅํฉํ if
์ ํตํด ์ฝ๋์ ๊ฐ๋
์ฑ๊ณผ ์ดํด๋๊ฐ ๋จ์ด์ง๋ค.
Bad Example
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;
}
์ค๋ฅ ์ฝ๋ ๋์ ์์ธ๋ฅผ ์ฌ์ฉํ๋ฉด ์ค๋ฅ ์ฒ๋ฆฌ ์ฝ๋๊ฐ ์๋ ์ฝ๋์์ ๋ถ๋ฆฌ๋๋ฏ๋ก ์ฝ๋๊ฐ ๊น๊ธํด์ง๋ค.
Good Example
try{
deletePage(page);
registry.deleteReference(page.name);
configKeys.deleteKey(page.name.makeKey());
}catch(Exception e){
logger.log(e.getMessage());
}
Try/Catch ๋ฝ์๋ด๊ธฐ
Try/Catch
๋ธ๋ก์ ๋ณ๋ก ํจ์๋ก ๋ฝ์๋ด๋ ํธ์ด ์ข๋ค.
Best Example
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());
}
์ค๋ฅ ์ฒ๋ฆฌ๋ ํ๊ฐ์ง ์์ ์ด๋ค.
public enum Error {
OK,
INVALID,
NO_SUCH,
LOCKED,
OUT_OF_RESOURCES,
WAITING_FOR_EVENT;
}
์ค๋ฅ ์ฝ๋๊ฐ ์ ์๋์ด์๋ค๋ฉด ์ ์ค๋ฅ ์ฝ๋๋ฅผ ์ถ๊ฐํ๊ธฐ ํ๋ค๊ณ ์ฌ์ปดํ์ผ/์ฌ๋ฐฐ์น๊ฐ ๋ฒ๊ฑฐ๋กญ๋ค.
๊ธฐ์กด์ java Exception
์ ์ฌ์ฉํ๊ฒ๋๋ค๋ฉด ์ฌ์ปดํ์ผ/์ฌ๋ฐฐ์น ์์ด๋ ์ ์์ธ ํด๋์ค๋ฅผ ์ถ๊ฐํ ์ ์๋ค.
๋ฐ๋ณตํ์ง ๋ง๋ผ!
์ค๋ณต์ ๋ชจ๋ ์ํํธ์จ์ด์์ ๋ชจ๋ ์ ์ ๊ทผ์์ด๋ฏ๋ก ๋ ์ค๋ณต์ ์์ ๋๋ก ๋ ธ๋ ฅํด์ผํ๋ค.
๊ตฌ์กฐ์ ํ๋ก๊ทธ๋๋ฐ
ํจ์๋ return๋ฌธ์ด ํ๋์ฌ์ผ ๋๋ฉฐ, ๋ฃจํ ์์์ break๋ continue๋ฅผ ์ฌ์ฉํด์ ์๋๋ฉฐ goto๋ ์ ๋๋ก, ์ ๋๋ก ์ฌ์ฉํ์ง ๋ง์.