item 5 lsucret - JAVA-JIKIMI/EFFECTIVE-JAVA3 GitHub Wiki

[item 5]μžμ›μ„ 직접 λͺ…μ‹œν•˜μ§€ 말고 의쑴 객체 μ£Όμž…μ„ μ‚¬μš©ν•˜λΌ

정적 μœ ν‹Έλ¦¬ν‹°λ‚˜ μ‹±κΈ€ν„΄ νŒ¨ν„΄μ„ μ‚¬μš©ν•΄ μ½”λ“œλ₯Ό 짜게 되면 ν•΄λ‹Ή κ°μ²΄λŠ” 였직 ν•œ μ’…λ₯˜μ˜ μΈμŠ€ν„΄μŠ€λ§Œ 생성할 수 μžˆλ‹€.

정적 μœ ν‹Έλ¦¬ν‹°λ₯Ό 잘λͺ» μ‚¬μš©ν•œ 예

//정적 μœ ν‹Έλ¦¬ν‹°
public class SpellChecker {
    private static final Lexicon dictionary = new Lexicon("english"); // 사전이 ν•˜λ‚˜λΏμ΄λ‹€.

    private SpellChecker() {} // 객체 생성 방지

    public static boolean isValid(String word) {...}
    public static List<String> suggestions(String typo) {...}
}

public class Main {
	public static void main(String[] args) {
		SpellChecker.isValid("hypopotamus");
  }
}

싱글턴을 잘λͺ» μ‚¬μš©ν•œ 예

//μ‹±κΈ€ν„΄
public class SpellChecker {
    private final Lexicon dictionary = new Lexicon(); // 사전이 ν•˜λ‚˜λΏμ΄λ‹€

    private SpellChecker() {} // 객체 생성 방지
    public static SpellChecker INSTANCE = new SpellChecker();

    public boolean isValid(String word) {}
    public List<String> suggestions(String type) {}
}

public class Main {
	public static void main(String[] args) {
		SpellChecker.INSTANCE.isValid("Hippopotamus");
  }
}
  • 사전 ν•˜λ‚˜λ§Œ 가지고 μ—¬λŸ¬ 상황에 λŒ€μ‘ν•˜λŠ” 것은 ν˜„μ‹€μ μœΌλ‘œ λΆˆκ°€λŠ₯
  • λ§Œμ•½ μ˜μ–΄ 사전 말고 쀑ꡭ어 사전이 ν•„μš”ν•˜λ‹€λ©΄? μ˜μ–΄ 쀑 특수 μš©μ–΄ 사전이 ν•„μš”ν•˜λ‹€λ©΄? ν…ŒμŠ€νŠΈμš© 사전이 ν•„μš”ν•˜λ‹€λ©΄?
  • μ—¬λŸ¬ 사전을 μ‚¬μš©ν•  수 μžˆλ„λ‘ μ½”λ“œ μˆ˜μ •μ΄ ν•„μš”

λŒ€μ•ˆ 1. ν•„λ“œμ—μ„œ final을 μ œκ±°ν•˜κ³  setter λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•΄ λ‹€λ₯Έ μ‚¬μ „μœΌλ‘œ κ΅μ²΄ν•œλ‹€

  • 였λ₯˜κ°€ λ°œμƒν•˜κΈ° 쉽고, (code, data heap μ˜μ—­μ„ κ³΅μœ ν•˜λŠ”) λ©€ν‹°μŠ€λ ˆλ“œ ν™˜κ²½μ—μ„œ μ‚¬μš©λΆˆκ°€

λŒ€μ•ˆ 2. 의쑴 객체 μ£Όμž… νŒ¨ν„΄μ„ μ‚¬μš©ν•œλ‹€.

// 의쑴 객체 μ£Όμž… νŒ¨ν„΄
public class SpellChecker {
    private final Lexicon dictionary;

    public SpellChecker(Lexicon dictionary) {
        this.dictionary = Objects.requireNonNull(dictionary);
    }

    public boolean isValid(String word) { return false;}
    public List<String> suggestions(String typo) { return null;}
}
  • dictionaryλΌλŠ” μžμ› ν•˜λ‚˜λ₯Ό μ‚¬μš©ν•œλ°λ‹€, μ™ΈλΆ€μ—μ„œ μ–΄λ–€ μ˜μ‘΄μ„±μ„ μ£Όμž…ν•˜λ˜μ§€ 상관없이 잘 λ™μž‘ν•œλ‹€.
  • final둜 λΆˆλ³€μ„ 보μž₯ν•˜μ—¬ μ—¬λŸ¬ ν΄λΌμ΄μ–ΈνŠΈκ°€ 의쑴 객체듀을 μ•ˆμ‹¬ν•˜κ³  κ³΅μœ ν•  수 μžˆλ‹€.

+νŒ©ν„°λ¦¬ λ©”μ„œλ“œ νŒ¨ν„΄

μœ μ‚¬ν•œ λ°©μ‹μœΌλ‘œ νŒ©ν„°λ¦¬ λ©”μ„œλ“œ νŒ¨ν„΄μ΄ μžˆλ‹€.

Mosaic create(Supplier<? extends Tile> tileFactory) { ... }
  • ν΄λΌμ΄μ–ΈνŠΈκ°€ μ œκ³΅ν•œ νŒ©ν„°λ¦¬κ°€ μƒμ„±ν•œ νƒ€μΌλ“€λ‘œ κ΅¬μ„±λœ λͺ¨μžμ΄ν¬λ₯Ό λ§Œλ“œλŠ” λ©”μ„œλ“œ
  • μžμ‹ μ΄ λͺ…μ‹œν•œ νƒ€μž…μ˜ ν•˜μœ„ νƒ€μž…μ΄λ©΄ 무엇이든 생성할 수 μžˆλŠ” νŒ©ν„°λ¦¬λ₯Ό λ„˜κΈ΄λ‹€.
  • μΈν„°νŽ˜μ΄μŠ€ Supplierκ°€ νŒ©ν„°λ¦¬λ₯Ό κ΅¬ν˜„ν•œ μ™„λ²½ν•œ 예둜, Supplierλ₯Ό μž…λ ₯으둜 λ°›λŠ” λ©”μ„œλ“œλŠ” 일반적으둜 ν•œμ •μ  μ™€μΌλ“œμΉ΄λ“œ νƒ€μž…(bounded wildcard type)을 μ‚¬μš©ν•΄ νŒ©ν„°λ¦¬μ˜ νƒ€μž… λ§€κ°œλ³€μˆ˜λ₯Ό μ œν•œν•œλ‹€.

μ˜μ‘΄κ°μ²΄μ£Όμž…μ˜ 단점

  • μ˜μ‘΄κ°μ²΄μ£Όμž…μ„ μ‚¬μš©ν•˜λ©΄ μœ μ—°μ„±κ³Ό ν…ŒμŠ€νŠΈ μš©μ΄μ„±μ„ κ°œμ„ ν•΄μ£Όμ§€λ§Œ, μ˜μ‘΄μ„± μ£Όμž…μ˜ μˆ˜κ°€ 늘 수둝 μ½”λ“œκ°€ μ–΄μ§€λŸ¬μ›Œμ§„λ‹€.
  • λŒ€κ±°(Dagger), 주슀(Guice), μŠ€ν”„λ§(Spring) 같은 의쑴 객체 μ£Όμž…μ„ λŒ€μ‹ ν•΄μ£ΌλŠ” ν”„λ ˆμž„μ›Œν¬λ₯Ό μ‚¬μš©ν•˜λ©΄ 이런 μ–΄μ§€λŸ¬μ›€μ„ ν•΄μ†Œν•  수 μžˆλ‹€.

정리

ν΄λž˜μŠ€κ°€ λ‚΄λΆ€μ μœΌλ‘œ ν•˜λ‚˜ μ΄μƒμ˜ μžμ›μ— μ˜μ‘΄ν•˜κ³  κ·Έ μžμ›μ΄ 클래슀 λ™μž‘μ— 영ν–₯을 μ€€λ‹€λ©΄ 의쑴 객체 μ£Όμž…μ„ μ‚¬μš©ν•˜λΌ. 의쑴 객체 μ£Όμž…μ€ 변경이 ν•„μš”μ—†λŠ” 뢀뢄은 κ·ΈλŒ€λ‘œ λ‘λ˜, 변경이 ν•„μš”ν•œ μžμ›μ„ μƒμ„±μžλ₯Ό 톡해 μ™ΈλΆ€μ—μ„œ μ£Όμž…λ°›μ•„ μ‚¬μš©ν•˜μž. 이 방법은 클래슀의 μœ μ—°μ„±, μž¬μ‚¬μš©μ„±, ν…ŒμŠ€νŠΈ μš©μ΄μ„±μ„ κ°œμ„ ν•΄μ€€λ‹€.

⚠️ **GitHub.com Fallback** ⚠️