Effective Java 3/E
μ μ ν©ν°λ¦¬ λ©μλμ public μμ±μλ κ°μμ μ°μμκ° μμΌλ μλμ μΈ μ₯λ¨μ μ μ΄ν΄νκ³ μ¬μ©νλ κ²μ΄ μ’κ² λ€. κ·Έλ λ€κ³ νλλΌλ μ μ ν©ν°λ¦¬λ₯Ό μ¬μ©νλκ² μ 리ν κ²½μ°κ° λ λ§μΌλ―λ‘ λ¬΄μμ public μμ±μλ₯Ό μ 곡νλ μ΅κ΄μ΄ μλ€λ©΄ κ³ μΉμ!
μμ΄ν 1: μμ±μ λμ μ μ ν©ν 리 λ©μλλ₯Ό κ³ λ €νλΌ
public class ClazzA {
private String name;
public ClazzA(String name) {
this.name = name;
}
public static void main(String[] args) {
ClazzA clazzA = new ClazzA("name");
}
}
ν΄λμ€μ μΈμ€ν΄μ€λ₯Ό μ»λ μ ν΅μ μΈ λ°©λ²μ public μμ±μλ₯Ό μ΄μ©νλ κ²μ λλ€. κ·Έλ μ§λ§ μμ±μμ 맀κ°λ³μλ§μ λ³΄κ³ μ΄λ€ κ°μ²΄κ° λ°νλ κ²μΈμ§ μμΈ‘νκΈ°κ° μ½μ§ μμ΅λλ€.
κ·Έλμ μ΄λ¬ν λ°©λ² λ§κ³ λͺ¨λ νλ‘κ·Έλλ¨Έκ° μμλ¬μΌ ν κΈ°λ²μ΄ νλ λ μμ΅λλ€. λ°λ‘ ν΄λμ€λ μμ±μμ λ³λλ‘ μ μ ν©ν 리 λ©μλ(static factory method)λ₯Ό μ 곡ν μ μλ€λ κ²μ λλ€.
ν©ν°λ¦¬ λ©μλ μ¬μ©μ ν΅ν΄ μ»λ μ₯μ 5κ°μ§
1. μ΄λ¦μ κ°μ§ μ μλ€.
valueOf μ κ°μ΄ λ©μλ λͺ μ ν΅ν΄ λ°νλ κ°μ²΄μ νΉμ±μ νν ν μ μμ΅λλ€.
public class ClazzA {
private String name;
public ClazzA(String name) {
this.name = name;
}
public static ClazzA valueOf(String name) {
return new ClazzA(name);
}
public static void main(String[] args) {
ClazzA clazzA = ClazzA.valueOf("name");
}
}
2. νΈμΆλ λ λ§λ€ μΈμ€ν΄μ€λ₯Ό μλ‘ μμ±νμ§ μμλ λλ€.
μΈμ€ν΄μ€λ₯Ό 미리 λ§λ€μ΄ λκ±°λ μΊμ±νμ¬ μ¬μ¬μ©νλ λ°©μμΌλ‘ λΆνμν κ°μ²΄ μμ±μ νΌν μ μμ΅λλ€.
class BooleanSample {
public static final Boolean TRUE = new Boolean(true);
public static final Boolean FALSE = new Boolean(false);
public static Boolean valueOf(boolean b) {
return (b ? TRUE : FALSE);
}
}
μ μ ν©ν 리 λ°©μμ ν΄λμ€λ μΈμ μ΄λ μΈμ€ν΄μ€λ₯Ό μ΄μ μκ² ν μ§λ₯Ό μ² μ ν ν΅μ ν μ μμ΅λλ€. μ΄λ° ν΄λμ€λ₯Ό μΈμ€ν΄μ€ ν΅μ ν΄λμ€ λΌκ³ ν©λλ€.
μΈμ€ν΄μ€λ₯Ό ν΅μ νλ μ΄μ λ?
- μΈμ€ν΄μ€λ₯Ό ν΅μ νλ©΄ ν΄λμ€λ₯Ό μ±κΈν€μΌλ‘, μΈμ€ν΄μ€ν λΆκ°λ‘ λ§λ€ μλ μμ΅λλ€.
- λΆλ³ κ° ν΄λμ€μμ λμΉμΈ μΈμ€ν΄μ€κ° λ¨ νλλΏμμ 보μ₯ν μ μμ΅λλ€. (a == bμΌ λλ§ a.equals(b) μ±λ¦½)
- μΈμ€ν΄μ€ ν΅μ λ νλΌμ΄μ¨μ΄νΈ ν¨ν΄μ κ·Όκ°μ΄ λλ©°, μ΄κ±° νμ μ μΈμ€ν΄μ€κ° νλλ§ λ§λ€μ΄μ§μ 보μ₯ν©λλ€.
νλΌμ΄μ¨μ΄νΈ(Flyweight pattern) ν¨ν΄μ΄λ?
λ°μ΄ν°λ₯Ό 곡μ νμ¬ λ©λͺ¨λ¦¬λ₯Ό μ μ½νλ ν¨ν΄, 곡ν΅μΌλ‘ μ¬μ©λλ κ°μ²΄λ νλ²λ§ μ¬μ©λκ³ Poolμ μν΄μ κ΄λ¦¬, μ¬μ©λλ€.
(JVMμ String Poolμμ κ°μ Stringμ΄ μλμ§ λ¨Όμ μ°Ύλλ€. [λΆλ³κ°μ²΄ String])
3. λ°ν νμ μ νμ νμ κ°μ²΄λ₯Ό λ°νν μ μλ€.
μ΄κ²μ μλ°μ λ€νμ±μ νΉμ§μ μ΄μ©νκΈ° λλ¬Έμ μμ²λκ² μ μ°ν μ½λ©μ ν μ μμ΅λλ€.
public class Collections {
private Collections() { }
public static final List EMPTY_LIST = new EmptyList<>();
@SuppressWarnings("unchecked")
public static final <T> List<T> emptyList() {
return (List<T>) EMPTY_LIST;
}
}
4. μ λ ₯ 맀κ°λ³μμ λ°λΌ λ§€λ² λ€λ₯Έ ν΄λμ€μ κ°μ²΄λ₯Ό λ°νν μ μλ€.
λ°ν νμ μ νμ νμ μ΄κΈ°λ§ νλ©΄ μ΄λ€ ν΄λμ€μ κ°μ²΄λ₯Ό λ°ννλ μκ΄μμ΅λλ€.
public class CarryUtil {
static Carrier getCarrier(int amount) {
if ( amount < 50 ) {
return new Pocket();
} else {
return new Backpack();
}
}
}
public interface Carrier {
}
class Pocket implements Carrier {
}
class Backpack implements Carrier {
}
5. μ μ ν©ν°λ¦¬ λ©μλλ₯Ό μμ±νλ μμ μλ λ°νν κ°μ²΄μ ν΄λμ€κ° μ‘΄μ¬νμ§ μμλ λλ€.
https://sysgongbu.tistory.com/95
ex) JDBC(Java Database Connectivity): μλΉμ€ μ 곡μ νλ μμν¬μμμ μ 곡μ(provider)λ μλΉμ€μ ꡬν체λ€. κ·Έλ¦¬κ³ μ΄ κ΅¬ν체λ€μ ν΄λΌμ΄μΈνΈμ μ 곡νλ μν μ νλ μμν¬κ° ν΅μ νμ¬ , ν΄λΌμ΄μΈνΈλ₯Ό ꡬν체λ‘λΆν° λΆλ¦¬ν΄μ€λ€.
μλΉμ€ μ 곡μ νλ μμν¬μ μ»΄ν¬λνΈ 3μμ
- μλΉμ€ μΈν°νμ΄μ€(service interface): ꡬν체μ λμμ μ μ
- μ 곡μ λ±λ‘ API (provider registration API): μ 곡μκ° κ΅¬ν체λ₯Ό λ±λ‘ν λ μ¬μ©
- μλΉμ€ μ κ·Ό API (service access API): ν΄λΌμ΄μΈνΈκ° μλΉμ€μ μΈμ€ν΄μ€λ₯Ό μ»μ λ μ¬μ©
μλλ jdbcλ₯Ό μ΄μ©νμ¬ db 컀λ₯μ μ λ§λλ μ½λμ΄λ€.
public static void main(String[] args) {
String driverName = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://localhost:3306/test";
String user = "root";
String password = "soyeon";
try {
Class.forName(driverName);
// μλΉμ€ μ κ·Ό APIμΈ DriverManager.getConnectionκ° μλΉμ€ ꡬν체(μλΉμ€ μΈν°νμ΄μ€)μΈ Connection λ°ν
Connection connection = DriverManager.getConnection(url, user, password);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
κ·Έλ°λ° Class.forNameμΌλ‘ λλΌμ΄λ² μ΄λ¦λ§ νΈμΆνλλ° μ΄λ»κ² DriverManagerκ° μ»€λ₯μ μ λ§λ€μ΄μ 리ν΄ν μ μμμκΉ?
1. Class.forName(String name) λ©μλμ μν΄ λ¬Έμμ΄λ‘ μ λ¬λλ "com.mysql.jdbc.Driver"μ΄λΌλ ν΄λμ€κ° λ©λͺ¨λ¦¬μ λ‘λ λλ€.
2. λ©λͺ¨λ¦¬μ λ‘λλλ©΄μ "com.mysql.jdbc.Driver" ν΄λμ€μ static μ μ΄ μ€νλλ€. μλμ κ°μ΄ DriverManager.registerDriver() λ©μλλ₯Ό ν΅ν΄ μκΈ° μμ μ λ±λ‘νλ€. μ¦, μ΄λ¬ν μ΄μ λ‘ Class.forName("com.mysql.jdbc.Driver") μ€νμ JDBC Driverκ° μλ λ±λ‘λλ€.
http://www.docjar.com/html/api/com/mysql/jdbc/Driver.java.html
3. λ±λ‘ν JDBC Driverλ λ°μ΄ν°λ² μ΄μ€ Connectionμ μμ±νλ μμ μ μ¬μ©λκ² λλ€.
μλ° κ°μλ¨Έμ μ΄ λμμ μμνκ³ , μ½λκ° μ€νλκΈ° μ κΉμ§λ μ΄λ€ JDBC λλΌμ΄λ²κ° μ¬μ©λ μ§ λͺ¨λ₯΄κΈ° λλ¬Έμ, λμ μΌλ‘ λλΌμ΄λ²λ₯Ό λ‘λ©νκΈ° μν΄ λ¦¬νλ μ (java.lang.reflect)μ μ΄μ©νλ€.
ν©ν°λ¦¬ λ©μλ μ¬μ©μ λ¨μ 2κ°μ§
1. μμμ νκΈ°μν΄μ public μ΄λ protected μμ±μκ° νμνλ μ μ ν©ν 리 λ©μλλ§ μ 곡νλ©΄ νμ ν΄λμ€λ₯Ό λ§λ€ μ μλ€.
2.μ μ ν©ν 리 λ©μλλ νλ‘κ·Έλλ¨Έκ° μ°ΎκΈ° μ΄λ ΅λ€.
- API μ€λͺ μ λͺ νν λλ¬λμ§ μμΌλ μ¬μ©μλ μ μ ν©ν 리 λ©μλ λ°©μ ν΄λμ€λ₯Ό μΈμ€ν΄μ€ννλ λ°©λ²μ μμλ΄μΌ νλ€.
μ μ ν©ν 리 λ©μλ λͺ λͺ κ·μΉ
μ μ ν©ν 리 λ©μλλ νΉμ§μ λ°λΌ λ©μλ λͺ μ μ§μ΄μΌ νλ€.
Date d = Date.from(instant);
- from: λ§€κ° λ³μλ₯Ό νλ λ°μμ ν΄λΉ νμ μ μΈμ€ν΄μ€ λ°ννλ νλ³ν λ©μλ.
Set faceCards = EnumSet.of(JACK, QUEEN, KING);
- of: μ¬λ¬ 맀κ°λ³μλ₯Ό λ°μ μ ν©ν νμ μ μΈμν΄μ€λ₯Ό λ°ννλ μ§κ³ λ©μλ
BigInteger prime = BigInteger.valueOf(Integer.MAX_VALUE);
- valueOf: fromκ³Ό ofμ λ μμΈν λ²μ
StackWalker luke = StackWalker.getInstance(options);
- intance or getInstance: (맀κ°λ³μλ₯Ό λ°λλ€λ©΄) 맀κ°λ³μλ‘ λͺ μν μΈμ€ν΄μ€λ₯Ό λ°ννμ§λ§, κ°μ μΈμ€ν΄μ€ μμ 보μ₯νμ§λ μλλ€
Object newArray = Array.newInstance(classObject, arrayLen);
- create or newInstance: instance or getInstanceμ κ°μ§λ§. λ§€λ² μλ‘μ΄ μΈμ€ν΄μ€λ₯Ό μμ±ν΄ λ°νν¨μ 보μ₯νλ€.
FileStore fs = Files.getFileStore(path);
- getType: getInstanceμ κ°μΌλ μμ±ν ν΄λμ€κ° μλ λ€λ₯Έ ν΄λμ€μ ν©ν°λ¦¬ λ©μλλ₯Ό μ μν λ μ΄λ€. "Type"μ ν©ν°λ¦¬ λ©μλκ° λ°νν κ°μ²΄μ νμ μ΄λ€.
List litany = Collections.list(legacyLitany);
- type: getType κ³Ό newTypeμ κ°κ²°ν λ²μ