item 1 Jung inchul - JAVA-JIKIMI/EFFECTIVE-JAVA3 GitHub Wiki
Effective Java 3e ์์ดํ 1์ ์์ฝํ ๋ด์ฉ ์ ๋๋ค.
ํด๋ผ์ด์ธํธ๊ฐ ํด๋์ค์ ์ธ์คํด์ค๋ฅผ ์ป๋ ์ ํต์ ์ธ ์๋จ์ public ์์ฑ์๋ค. ํด๋์ค๋ ์์ฑ์์ ๋ณ๋๋ก ์ ์ ํฉํฐ๋ฆฌ ๋ฉ์๋๋ฅผ ์ ๊ณตํ ์ ์๋ค.
์ ์ ํฉํฐ๋ฆฌ ๋ฉ์๋๋?
๊ฐ์ฒด ์์ฑ์ ์บก์ํํ๋ ๊ธฐ๋ฒ์ด๋ค. ์ข ๋ ๊ตฌ์ฒด์ ์ผ๋ก๋ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ๋ฉ์๋๋ฅผ ๋ง๋ค๊ณ , static์ผ๋ก ์ ์ธํ๋ ๊ธฐ๋ฒ์ด๋ค. ํด๋์ค๋ ํด๋ผ์ด์ธํธ์ public ์์ฑ์ ๋์ (ํน์ ์์ฑ์์ ํจ๊ป) ์ ์ ํฉํฐ๋ฆฌ ๋ฉ์๋๋ฅผ ์ ๊ณตํ ์ ์๋ค.
๋จผ์ ์ ์ ํฉํฐ๋ฆฌ ๋ฉ์๋๊ฐ ์์ฑ์๋ณด๋ค ์ข์ ์ฅ์ ๋ค์ฏ ๊ฐ์ง๋ฅผ ์์๋ณด์
์์ฑ์์ ๋๊ธฐ๋ ๋งค๊ฐ๋ณ์์ ์์ฑ์ ์์ฒด๋ง์ผ๋ก๋ ๋ฐํ๋ ๊ฐ์ฒด์ ํน์ฑ์ ์ ๋๋ก ์ค๋ช ํ์ง ๋ชปํ๋ค. ๋ฐ๋ฉด ์ ์ ํฉํฐ๋ฆฌ๋ ์ด๋ฆ๋ง ์ ์ง์ผ๋ฉด ๋ฐํ๋ ๊ฐ์ฒด์ ํน์ฑ์ ์ฝ๊ฒ ๋ฌ์ฌํ ์ ์๋ค.
// ๊ฐ์ด ์์์ธ BigInteger๋ฅผ ์์ฑํ๋ค.
// ์ผ๋ฐ ์์ฑ์๋ก ์์ฑํ ๊ฐ์ฒด
BigInteger num = new BigInteger(0, 0, new Random());
// ์ ์ ํฉํฐ๋ฆฌ ๋ฉ์๋๋ก ์์ฑํ ๊ฐ์ฒด
BigInteger num2 = BigInteger.probablePrime();
ํ๋์ ์๊ทธ๋์ฒ๋ก๋ ์์ฑ์๋ฅผ ํ๋๋ง ๋ง๋ค ์ ์๋ค. ์ ๋ ฅ ๋งค๊ฐ๋ณ์๋ค์ ์์๋ฅผ ๋ค๋ฅด๊ฒ ํ ์์ฑ์๋ฅผ ์๋ก ์ถ๊ฐํ๋ ์์ผ๋ก ์ด ์ ํ์ ํผํด๋ณผ ์๋ ์์ง๋ง ์ข์ง ์์ ๋ฐ์์ด๋ค.
์ด๋ฆ์ ๊ฐ์ง ์ ์๋ ์ ์ ํฉํฐ๋ฆฌ ๋ฉ์๋์๋ ์ด๋ฐ ์ ์ฝ์ด ์๋ค. ํ ํด๋์ค์ ์๊ทธ๋์ฒ๊ฐ ๊ฐ์ ์์ฑ์๊ฐ ์ฌ๋ฌ ๊ฐ ํ์ํ ๊ฒ ๊ฐ์ผ๋ฉด ์์ฑ์๋ฅผ ์ ์ ํฉํฐ๋ฆฌ ๋ฉ์๋๋ก ๋ฐ๊พธ๊ณ ๊ฐ๊ฐ์ ์ฐจ์ด๋ฅผ ์ ๋๋ฌ๋ด๋ ์ด๋ฆ์ ์ง์ด์ฃผ์
๋ํ์ ์ธ ์๋ก Boolean.valueOf(boolean) ๋ฉ์๋๋ ๊ฐ์ฒด๋ฅผ ์์ ์์ฑํ์ง ์๋๋ค. ๋ฐ๋ผ์ (ํนํ ์์ฑ ๋น์ฉ์ด ํฐ) ๊ฐ์ ๊ฐ์ฒด๊ฐ ์์ฃผ ์์ฒญ๋๋ ์ํฉ์ด๋ผ๋ฉด ์ฑ๋ฅ์ ์๋นํ ๋์ด์ฌ๋ ค ์ค๋ค. ํ๋ผ์ด์จ์ดํธ ํจํด๋ ์ด์ ๋น์ทํ ๊ธฐ๋ฒ์ด๋ผ ํ ์ ์๋ค.
public static Boolean valueOf(boolean b){
return b ? Boolean.TRUE : Boolean.FALSE;
}
๋ฐ๋ณต๋๋ ์์ฒญ์ ๊ฐ์ ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ ์์ผ๋ก ์ ์ ํฉํฐ๋ฆฌ ๋ฐฉ์์ ํด๋์ค๋ ์ธ์ ์ด๋ ์ธ์คํด์ค๋ฅผ ์ด์ ์๊ฒ ํ ์ง๋ฅผ ์ฒ ์ ํ ํต์ ํ ์ ์๋ค. ์ด๋ฐ ํด๋์ค๋ฅผ ์ธ์คํด์ค ํต์ ํด๋์ค๋ผ ํ๋ค.
ํ๋ผ์ด์จ์ดํธ ํจํด์ด๋?
๋ฐ์ดํฐ๋ฅผ ๊ณต์ ์ฌ์ฉํ์ฌ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ ์ฝํ ์ ์๋ ํจํด์ด๋ค. ์ผ๋ฐ์ ์ผ๋ก ๊ณตํต์ผ๋ก ์ฌ์ฉ๋๋ ๊ฐ์ฒด๋ ์๋ก ์์ฑํด์ ์ฌ์ฉํ์ง ์๊ณ ๊ณต์ ๋ฅผ ํตํด ํจ์จ์ ์ผ๋ก ์์์ ํ์ฉํ๋ค. ํ๋ฒ ์์ฑ๋ ๊ฐ์ฒด๋ ๋๋ฒ ์์ฑ๋์ง ์๊ณ , ํ(Pool)์ ์ํด์ ๊ด๋ฆฌ ๋ฐ ์ฌ์ฉ๋๋ค.
// Flyweight ํจํด ์ ์ฉ ์ฌ๋ก
public class Test{
public static void main(String[] args){
String s = "hello";
String s1 = new String("hello");
String s2 = "hello";
System.out.println("s == s1 ? " + (s == s1)); // false
System.out.println("s == s2 ? " + (s == s2)); // true
}
}
์ธ์คํด์ค๋ฅผ ํต์ ํ๋ ์ด์ ๋ ๋ฌด์์ผ๊น?
- ์ธ์คํด์ค๋ฅผ ํต์ ํ๋ฉด ํด๋์ค๋ฅผ ์ฑ๊ธํด์ผ๋ก ๋ง๋ค ์๋ ์ธ์คํด์คํ ๋ถ๊ฐ๋ก ๋ง๋ค์๋ ์๋ค.
- ๋ถ๋ณ ๊ฐ ํด๋์ค์์ ๋์น์ธ ์ธ์คํด์ค๊ฐ ๋จ ํ๋๋ฟ์์ ๋ณด์ฅํ ์ ์๋ค.
์ด ํน์ง์ ๋ฐํํ ๊ฐ์ฒด์ ํด๋์ค๋ฅผ ์์ ๋กญ๊ฒ ์ ํํ ์ ์๊ฒ ํ๋ '์์ฒญ๋ ์ ์ฐ์ฑ'์ ์ ๊ณตํ๋ค. ์ด๋ ์ธํฐํ์ด์ค๋ฅผ ์ ์ ํฉํฐ๋ฆฌ ๋ฉ์๋์ ๋ฐํ ํ์ ์ผ๋ก ์ฌ์ฉํ๋ ์ธํฐํ์ด์ค ๊ธฐ๋ฐ ํ๋ ์์ํฌ๋ฅผ ๋ง๋๋ ํต์ฌ ๊ธฐ์ ์ด๊ธฐ๋ ํ๋ค.
์ปฌ๋ ์ ํ๋ ์์ํฌ๋ ์ด 45๊ฐ ํด๋์ค๋ฅผ ๊ณต๊ฐํ์ง ์๊ธฐ ๋๋ฌธ์ API ์ธ๊ฒฌ์ ํจ์ฌ ์๊ฒ ๋ง๋ค ์ ์์๋ค. API๊ฐ ์์์ง ๊ฒ์ ๋ฌผ๋ก ๊ฐ๋ ์ ์ธ ๋ฌด๊ฒ, ์ฆ ํ๋ก๊ทธ๋๋จธ๊ฐ API๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด ์ตํ์ผ ํ๋ ๊ฐ๋ ์ ์์ ๋์ด๋๋ ๋ฎ์ท๋ค.
์๋ฐ 8๋ถํฐ๋ ์ธํฐํ์ด์ค๊ฐ ์ ์ ๋ฉ์๋๋ฅผ ๊ฐ์ง ์ ์๋ค๋ ์ ํ์ด ํ๋ ธ๊ธฐ ๋๋ฌธ์ ์ธ์คํด์คํ ๋ถ๊ฐ ๋๋ฐ ํด๋์ค๋ฅผ ๋ ์ด์ ๊ฐ ๋ณ๋ก ์๋ค.
์๋ฐ 9์์๋ private ์ ์ ๋ฉ์๋๊น์ง ํ๋ฝํ์ง๋ง ์ ์ ํ๋์ ์ ์ ๋ฉค๋ฒ ํด๋์ค๋ ์ฌ์ ํ public์ด์ด์ผ ํ๋ค.
public interface Pizza {
void cook();
public static BulgogiPizza(String topping){
return new BulgogiPizza(topping);
}
}
public class BulgogiPizza implements Pizza{ ... }
EnumSet ํด๋์ค๋ public ์์ฑ์ ์์ด ์ค์ง ์ ์ ํฉํฐ๋ฆฌ๋ง ์ ๊ณตํ๋๋ฐ, OpenJDK์์๋ ์์์ ์์ ๋ฐ๋ผ ๋ ๊ฐ์ง ํ์ ํด๋์ค ์ค ํ๋์ ์ธ์คํด์ค๋ฅผ ๋ฐํํ๋ค.
์์๊ฐ 64๊ฐ ์ดํ๋ฉด ์์๋ค์ long ๋ณ์ ํ๋๋ก ๊ด๋ฆฌํ๋ RegularEnumSet์ ์ธ์คํด์ค, 65๊ฐ ์ด์์ด๋ฉด JumboEnumSet์ ์ธ์คํด์ค๋ฅผ ๋ฐํํ๋ค.
ํด๋ผ์ด์ธํธ๋ ํฉํฐ๋ฆฌ๊ฐ ๊ฑด๋ค์ฃผ๋ ๊ฐ์ฒด๊ฐ ์ด๋ ํด๋์ค์ ์ธ์คํด์ค์ธ์ง ์ ์๋ ์๊ณ ์ ํ์๋ ์๋ค. EnumSet์ ํ์ ํด๋์ค์ด๊ธฐ๋ง ํ๋ฉด ๋๋ ๊ฒ์ด๋ค.
public interface Pizza {
void cook();
public static BakedPizza(Boolean isVegiterian, String topping){
return isVegiterian ? new VegitablePizza(topping); : new BulgogiPizza(topping);
}
}
public class BulgogiPizza implements Pizza{ ... }
public class VegitablePizza implements Pizza{ ... }
5. ์ ์ ํฉํฐ๋ฆฌ ๋ฉ์๋๋ฅผ ์์ฑํ๋ ์์ ์๋ ๋ฐํํ ๊ฐ์ฒด์ ํด๋์ค๊ฐ ์กด์ฌํ์ง ์์๋ ๋๋ค.
๋ํ์ ์ธ ์๋น์ค ์ ๊ณต์ ํ๋ ์์ํฌ๋ก๋ JDBC๊ฐ ์๋ค.
์๋น์ค ์ ๊ณต์ ํ๋ ์์ํฌ๋ 3๊ฐ์ ํต์ฌ ์ปดํฌ๋ํธ๋ก ์ด๋ค์ง๋ค. ๊ตฌํ์ฒด์ ๋์์ ์ ์ํ๋ ์๋น์ค ์ธํฐํ์ด์ค, ์ ๊ณต์๊ฐ ๊ตฌํ์ฒด๋ฅผ ๋ฑ๋กํ ๋ ์ฌ์ฉํ๋ ์ ๊ณต์ ๋ฑ๋ก API, ํด๋ผ์ด์ธํธ๊ฐ ์๋น์ค์ ์ธ์คํด์ค๋ฅผ ์ป์ ๋ ์ฌ์ฉํ๋ ์๋น์ค ์ ๊ทผ API๊ฐ ๊ทธ ์ฃผ์ธ๊ณต์ด๋ค.
ํด๋ผ์ด์ธํธ๋ ์๋น์ค ์ ๊ทผ API๋ฅผ ์ฌ์ฉํ ๋ ์ํ๋ ๊ตฌํ์ฒด์ ์กฐ๊ฑด์ ๋ช ์ํ ์ ์๋ค. ์กฐ๊ฑด์ ๋ช ์ํ์ง ์์ผ๋ฉด ๊ธฐ๋ณธ ๊ตฌํ์ฒด๋ฅผ ๋ฐํํ๊ฑฐ๋ ์ง์ํ๋ ๊ตฌํ์ฒด๋ค์ ํ๋์ฉ ๋์๊ฐ๋ฉฐ ๋ฐํํ๋ค. ์ด ์๋น์ค ์ ๊ทผ API๊ฐ ๋ฐ๋ก ์๋น์ค ์ ๊ณต์ ํ๋ ์์ํฌ์ ๊ทผ๊ฐ์ด๋ผ๊ณ ํ '์ ์ฐํ ์ ์ ํฉํฐ๋ฆฌ'์ ์ค์ฒด๋ค.
JDBC์์๋ Connection์ด ์๋น์ค ์ธํฐํ์ด์ค ์ญํ ์, DriverManager.registerDriver๊ฐ ์ ๊ณต์ ๋ฑ๋ก API ์ญํ ์, Driver๊ฐ ์๋น์ค ์ ๊ณต์ ์ธํฐํ์ด์ค ์ญํ ์ ์ํํ๋ค.
1. ์์์ ํ๋ ค๋ฉด public ์ด๋ protected ์์ฑ์๊ฐ ํ์ํ๋ ์ ์ ํฉํฐ๋ฆฌ ๋ฉ์๋๋ง ์ ๊ณตํ๋ฉด ํ์ ํด๋์ค๋ฅผ ๋ง๋ค ์ ์๋ค.
์ด ์ ์ฝ์ ์์๋ณด๋ค๋ ์ปดํฌ์ง์ ์ ์ฌ์ฉํ๋๋ก ์ ๋ํ๊ณ ๋ถ๋ณ ํ์ ์ผ๋ก ๋ง๋ค๋ ค๋ฉด ์ด ์ ์ฝ์ ์ง์ผ์ผ ํ๋ค๋ ์ ์์ ์คํ๋ ค ์ฅ์ ์ผ๋ก ๋ฐ์๋ค์ผ ์๋ ์๋ค.
์์ฑ์์ฒ๋ผ API ์ค๋ช ์ ๋ช ํํ ๋๋ฌ๋์ง ์์ผ๋ ์ฌ์ฉ์๋ ์ ์ ํฉํฐ๋ฆฌ ๋ฉ์๋ ๋ฐฉ์ ํด๋์ค๋ฅผ ์ธ์คํด์คํํ ๋ฐฉ๋ฒ์ ์์๋ด์ผ ํ๋ค.
| Method | Example |
|---|---|
| from | Date d = Date.from(instance); |
| of | EnumSet.of(JACK | QUEEN | KING) |
| valueof | BigInteger.valueOf(Integer.MAX_VALUE) |
| instance | getInstance |
| create | newInstance |
| getType | Files.getFileStore(path) |
| newType | Files.newBufferedReader(path) |
| type | Collections.list(legacyLitany); |
์ ์ ํฉํฐ๋ฆฌ ๋ฉ์๋์ public ์์ฑ์๋ ๊ฐ์์ ์ฐ์์๊ฐ ์์ผ๋ ์๋์ ์ธ ์ฅ๋จ์ ์ ์ดํดํ๊ณ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข๋ค. ๊ทธ๋ ๋ค๊ณ ํ๋๋ผ๋ ์ ์ ํฉํฐ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ ์ ๋ฆฌํ ๊ฒฝ์ฐ๊ฐ ๋ ๋ง์ผ๋ฏ๋ก ๋ฌด์์ public ์์ฑ์๋ฅผ ์ ๊ณตํ๋ ์ต๊ด์ด ์๋ค๋ฉด ๊ณ ์น์!