관리 메뉴

Unfazedβ—οΈπŸŽ―

[μ΄νŽ™ν‹°λΈŒ μžλ°”] μ•„μ΄ν…œ 1: μƒμ„±μž λŒ€μ‹  정적 νŒ©ν„°λ¦¬ λ©”μ„œλ“œλ₯Ό κ³ λ €ν•˜λΌ λ³Έλ¬Έ

λ…μ„œ

[μ΄νŽ™ν‹°λΈŒ μžλ°”] μ•„μ΄ν…œ 1: μƒμ„±μž λŒ€μ‹  정적 νŒ©ν„°λ¦¬ λ©”μ„œλ“œλ₯Ό κ³ λ €ν•˜λΌ

9taetae9 2025. 9. 6. 15:11
728x90

new ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•œ 객체 생성은 μžλ°” κ°œλ°œμžμ—κ²Œ κ°€μž₯ μ΅μˆ™ν•œ λ°©λ²•μž…λ‹ˆλ‹€. ν•˜μ§€λ§Œ λ•Œλ‘œλŠ” 이 방식이 μ½”λ“œμ˜ μ˜λ„λ₯Ό λͺ…ν™•ν•˜κ²Œ λ“œλŸ¬λ‚΄μ§€ λͺ»ν•˜κ±°λ‚˜, λΆˆν•„μš”ν•œ 객체λ₯Ό 계속 λ§Œλ“€μ–΄λ‚΄λŠ” 원인이 λ˜κΈ°λ„ ν•©λ‹ˆλ‹€.

이럴 λ•Œ μƒμ„±μžμ˜ 쒋은 λŒ€μ•ˆμ΄ λ˜λŠ” 것이 λ°”λ‘œ 정적 νŒ©ν„°λ¦¬ λ©”μ„œλ“œ(Static Factory Method)μž…λ‹ˆλ‹€. λ‹¨μˆœνžˆ new ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜λŠ” λŒ€μ‹ , 의미 μžˆλŠ” 이름을 κ°€μ§„ 정적 λ©”μ„œλ“œλ₯Ό 톡해 객체λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€. 이λ₯Ό 톡해 가독성과 μœ μ—°μ„±μ„ 크게 ν–₯μƒμ‹œν‚€κ³ , 더 효율적인 λ©”λͺ¨λ¦¬ 관리λ₯Ό ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

 

이번 κΈ€μ—μ„œλŠ” μ΄νŽ™ν‹°λΈŒ μžλ°” 3판 μ•„μ΄ν…œ 1 "μƒμ„±μž λŒ€μ‹  정적 νŒ©ν„°λ¦¬ λ©”μ„œλ“œλ₯Ό κ³ λ €ν•˜λΌ"의 λ‚΄μš©μ„ 기반으둜 정적 νŒ©ν„°λ¦¬ λ©”μ„œλ“œμ˜ 5κ°€μ§€ 핡심 μž₯점과 단점을 예제 μ½”λ“œμ™€ ν•¨κ»˜ μ•Œμ•„λ³΄κ² μŠ΅λ‹ˆλ‹€.

 

1. 정적 νŒ©ν„°λ¦¬ λ©”μ„œλ“œμ˜ 5κ°€μ§€ 핡심 μž₯점

1-1. 이름을 κ°€μ§ˆ 수 μžˆμ–΄ μ˜λ„λ₯Ό λͺ…ν™•νžˆ ν‘œν˜„ν•  수 μžˆλ‹€.

 μƒμ„±μžλŠ” 클래슀 이름과 동일해야 ν•˜κ³ , λ§€κ°œλ³€μˆ˜μ˜ νƒ€μž…κ³Ό μˆœμ„œλ‘œλ§Œ μ„œλ‘œλ₯Ό κ΅¬λΆ„ν•©λ‹ˆλ‹€. 이 λ•Œλ¬Έμ— λ§€κ°œλ³€μˆ˜λ§Œ λ΄μ„œλŠ” 객체가 μ–΄λ–€ μƒνƒœλ‘œ μƒμ„±λ˜λŠ”μ§€ νŒŒμ•…ν•˜κΈ° μ–΄λ €μšΈ λ•Œκ°€ λ§ŽμŠ΅λ‹ˆλ‹€.

 λ°˜λ©΄ 정적 νŒ©ν„°λ¦¬ λ©”μ„œλ“œλŠ” 자유둭게 이름을 지을 수 μžˆμ–΄, λ©”μ„œλ“œ 이름 μžμ²΄κ°€ λ¬Έμ„œν™” 역할을 ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

λ³΅μ†Œμˆ˜(Complex Number)λ₯Ό μƒμ„±ν•˜λŠ” 예둜 차이λ₯Ό μ΄ν•΄ν•΄λ΄…μ‹œλ‹€. 

// Before: μƒμ„±μž μ‚¬μš© - μ˜λ„κ°€ λΆˆλΆ„λͺ…
ComplexNumber c1 = new ComplexNumber(3, 4);  // μ’Œν‘œμΈκ°€? μ‹€μˆ˜λΆ€μ™€ ν—ˆμˆ˜λΆ€μΈκ°€? 
ComplexNumber c2 = new ComplexNumber(5, Math.PI/4, true);  // 무엇을 μ˜λ―Έν•˜λŠ”κ°€?

// After: 정적 νŒ©ν„°λ¦¬ λ©”μ„œλ“œ - μ˜λ„κ°€ λͺ…ν™•
ComplexNumber c1 = ComplexNumber.ofRectangular(3, 4);  // μ§κ΅μ’Œν‘œκ³„
ComplexNumber c2 = ComplexNumber.ofPolar(5, Math.PI/4);  // κ·Ήμ’Œν‘œκ³„
ComplexNumber c3 = ComplexNumber.ofImaginary(7);  // ν—ˆμˆ˜

이처럼 ofRectangular, ofPolar 같은 이름은 λ§€κ°œλ³€μˆ˜μ˜ 의미λ₯Ό μ™„λ²½ν•˜κ²Œ μ„€λͺ…ν•΄ μ€λ‹ˆλ‹€.

 

1-2.  호좜될 λ•Œλ§ˆλ‹€ μΈμŠ€ν„΄μŠ€λ₯Ό μƒˆλ‘œ μƒμ„±ν•˜μ§€ μ•Šμ•„λ„ λœλ‹€.

정적 νŒ©ν„°λ¦¬ λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜λ©΄ 미리 λ§Œλ“€μ–΄ λ‘” μΈμŠ€ν„΄μŠ€λ‚˜ μΊμ‹±λœ μΈμŠ€ν„΄μŠ€λ₯Ό λ°˜ν™˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 이 덕뢄에 λΆˆν•„μš”ν•œ 객체 생성을 ν”Όν•΄ μ„±λŠ₯을 크게 ν–₯μƒμ‹œν‚¬ 수 μžˆμŠ΅λ‹ˆλ‹€. 특히 생성 λΉ„μš©μ΄ 큰 κ°μ²΄λ‚˜, 반볡적으둜 λ™μΌν•œ 객체가 μš”μ²­λ  λ•Œ 맀우 μœ μš©ν•©λ‹ˆλ‹€.

κ°€μž₯ λŒ€ν‘œμ μΈ μ˜ˆλŠ” Boolean.valueOf(boolean) λ©”μ„œλ“œμž…λ‹ˆλ‹€.

// Boolean.valueOf()λŠ” μƒˆλ‘œμš΄ 객체λ₯Ό μƒμ„±ν•˜μ§€ μ•Šκ³ ,
// 미리 μƒμ„±λœ Boolean.TRUE λ˜λŠ” Boolean.FALSEλ₯Ό λ°˜ν™˜
Boolean isTrue1 = Boolean.valueOf(true);
Boolean isTrue2 = Boolean.valueOf(true);

// isTrue1κ³Ό isTrue2λŠ” μ™„μ „νžˆ λ™μΌν•œ μΈμŠ€ν„΄μŠ€λ₯Ό μ°Έμ‘°
System.out.println(isTrue1 == isTrue2); // 좜λ ₯: true

μ΄λ ‡κ²Œ λ°˜λ³΅λ˜λŠ” μš”μ²­μ— λ™μΌν•œ 객체λ₯Ό λ°˜ν™˜ν•˜λŠ” μ‹μœΌλ‘œ μ–Έμ œ μ–΄λŠ μΈμŠ€ν„΄μŠ€λ₯Ό μ‚΄μ•„ 있게 ν• μ§€λ₯Ό μ² μ €νžˆ ν†΅μ œ ν•  수 μžˆλŠ” 클래슀λ₯Ό μΈμŠ€ν„΄μŠ€ ν†΅μ œ(Instance Control) 클래슀라고 ν•©λ‹ˆλ‹€. ν΄λž˜μŠ€κ°€ μƒμ„±λ˜λŠ” μΈμŠ€ν„΄μŠ€μ˜ 수λ₯Ό ν†΅μ œν•˜μ—¬ μ‹±κΈ€ν„΄(Singleton) νŒ¨ν„΄μ„ κ΅¬ν˜„ν•˜κ±°λ‚˜, ν”ŒλΌμ΄μ›¨μ΄νŠΈ(Flyweight) νŒ¨ν„΄μ˜ κΈ°λ°˜μ„ λ§ˆλ ¨ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

1-3. λ°˜ν™˜ νƒ€μž…μ˜ ν•˜μœ„ νƒ€μž… 객체λ₯Ό λ°˜ν™˜ν•  수 μžˆλŠ” λŠ₯λ ₯이 μžˆλ‹€.

이 λŠ₯λ ₯은 정적 νŒ©ν„°λ¦¬ λ©”μ„œλ“œκ°€ κ°€μ§„ μ—„μ²­λ‚œ μœ μ—°μ„±μ˜ ν•΅μ‹¬μž…λ‹ˆλ‹€. λ©”μ„œλ“œμ— μ„ μ–Έλœ λ°˜ν™˜ νƒ€μž…μ€ μΈν„°νŽ˜μ΄μŠ€λ‚˜ 좔상 ν΄λž˜μŠ€κ°€ 될 수 있고, μ‹€μ œλ‘œλŠ” κ·Έ ν•˜μœ„ νƒ€μž…μ˜ κ΅¬ν˜„μ²΄ 객체λ₯Ό 자유둭게 μ„ νƒν•΄μ„œ λ°˜ν™˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

μ΄λŸ¬ν•œ μœ μ—°μ„± 덕뢄에 μš°λ¦¬λŠ” κ΅¬ν˜„ 클래슀λ₯Ό 외뢀에 λ…ΈμΆœν•˜μ§€ μ•Šκ³ λ„ ν΄λΌμ΄μ–ΈνŠΈμ—κ²Œ 객체λ₯Ό μ œκ³΅ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 결과적으둜, APIλ₯Ό 맀우 μž‘κ³  κ°„κ²°ν•˜κ²Œ μœ μ§€ν•  수 있게 λ©λ‹ˆλ‹€.

 

μžλ°” μ»¬λ ‰μ…˜ ν”„λ ˆμž„μ›Œν¬κ°€ 이 방식을 잘 ν™œμš©ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

Java 8 이전: λ™λ°˜ 클래슀 Collections ν™œμš©

java8 μ΄μ „μ—λŠ” μΈν„°νŽ˜μ΄μŠ€μ— 정적 λ©”μ„œλ“œλ₯Ό μ„ μ–Έν•  수 μ—†μ–΄μ„œ, Collections와 같은 λ³„λ„μ˜ μœ ν‹Έλ¦¬ν‹° 클래슀(λ™λ°˜ 클래슀)λ₯Ό μ‚¬μš©ν–ˆμŠ΅λ‹ˆλ‹€.

import java.util.*;

public class Java8Style {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("c");

        // Collections.unmodifiableListλŠ” μˆ˜μ • λΆˆκ°€λŠ₯ν•œ 리슀트λ₯Ό λ°˜ν™˜
        List<String> unmodifiable = Collections.unmodifiableList(list);

        // ν΄λΌμ΄μ–ΈνŠΈλŠ” 'List' μΈν„°νŽ˜μ΄μŠ€ νƒ€μž…μœΌλ‘œ 객체λ₯Ό λ‹€λ£Έ
        System.out.println(unmodifiable);
        
        // μ‹€μ œ κ΅¬ν˜„μ²΄μ˜ νƒ€μž…: λ‚΄λΆ€ 클래슀인 UnmodifiableRandomAccessList
        // 이 ν΄λž˜μŠ€λŠ” 외뢀에 κ³΅κ°œλ˜μ–΄ μžˆμ§€ μ•ŠμŒ
        System.out.println(unmodifiable.getClass());
        // 좜λ ₯: class java.util.Collections$UnmodifiableRandomAccessList
    }
}

 

Java  8 이후 (μΈν„°νŽ˜μ΄μŠ€ μ•ˆμ— 직접 static λ©”μ„œλ“œ)

μžλ°” 8λΆ€ν„° μΈν„°νŽ˜μ΄μŠ€μ— public 정적 λ©”μ„œλ“œλ₯Ό μ„ μ–Έν•  수 있게 λ˜μ—ˆμŠ΅λ‹ˆλ‹€. 이 덕뢄에 기쑴의 λ™λ°˜ ν΄λž˜μŠ€κ°€ ν•˜λ˜ 역할을 μΈν„°νŽ˜μ΄μŠ€κ°€ 직접 μˆ˜ν–‰ν•  수 있게 λ˜μ—ˆμŠ΅λ‹ˆλ‹€. λ˜ν•œ, Java 9μ—μ„œλŠ” List.of(), Set.of() 와 같은 νŽΈλ¦¬ν•œ μ»¬λ ‰μ…˜ 정적 νŒ©ν„°λ¦¬ λ©”μ„œλ“œλ“€μ΄ λŒ€κ±° μΆ”κ°€λ˜λ©΄μ„œ 이 νŒ¨ν„΄μ΄ λ”μš± 널리 μ“°μ΄κ²Œ λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

import java.util.List;

public class Java9Style {
    public static void main(String[] args) {
        // 더 이상 Collections ν΄λž˜μŠ€κ°€ ν•„μš” μ—†μŒ
        // List μΈν„°νŽ˜μ΄μŠ€κ°€ 직접 λΆˆλ³€ 리슀트λ₯Ό 생성
        List<String> unmodifiable = List.of("a", "b", "c");

        System.out.println(unmodifiable);
        
        // μ‹€μ œ κ΅¬ν˜„μ²΄λŠ” μ—¬μ „νžˆ 내뢀에 감좰진 ImmutableCollections$ListN
        System.out.println(unmodifiable.getClass());
        // 좜λ ₯: class java.util.ImmutableCollections$ListN
    }
}

μ™œ κ΅¬ν˜„μ²΄λ₯Ό 감좜까?

 

  • API λ‹¨μˆœν™”: κ°œλ°œμžλŠ” List μΈν„°νŽ˜μ΄μŠ€λ§Œ μ•Œλ©΄ μΆ©λΆ„ν•©λ‹ˆλ‹€. μˆ˜μ‹­ 개의 λ‚΄λΆ€ κ΅¬ν˜„ 클래슀 이름을 μ•Œ ν•„μš”κ°€ μ—†μŠ΅λ‹ˆλ‹€.
  • κ΅¬ν˜„ ꡐ체의 자유: JDK νŒ€μ΄ λ‚˜μ€‘μ— 더 효율적인 자료ꡬ쑰λ₯Ό κ°œλ°œν•˜λ”λΌλ„, ν΄λΌμ΄μ–ΈνŠΈ μ½”λ“œμ— 영ν–₯을 μ£Όμ§€ μ•Šκ³  λ‚΄λΆ€ κ΅¬ν˜„μ²΄λ₯Ό ꡐ체할 수 μžˆμŠ΅λ‹ˆλ‹€.
  • λΆˆλ³€μ„± 보μž₯: List.of()둜 얻은 λ¦¬μŠ€νŠΈλŠ” μˆ˜μ •μ΄ λΆˆκ°€λŠ₯ν•©λ‹ˆλ‹€. λ§Œμ•½ λ‚΄λΆ€ κ΅¬ν˜„ ν΄λž˜μŠ€κ°€ public이라면, λˆ„κ΅°κ°€ 이λ₯Ό μƒμ†ν•˜μ—¬ λΆˆλ³€ κ·œμΉ™μ„ 깨트릴 μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€. package-private으둜 접근을 막아 이런 μœ„ν—˜μ„ μ›μ²œ μ°¨λ‹¨ν•©λ‹ˆλ‹€.

직접 이 방식을 μ μš©ν•΄λ΄…μ‹œλ‹€.

 

// Shape.java - 곡개 API (μΈν„°νŽ˜μ΄μŠ€)
public interface Shape {
    double area();

    // 정적 νŒ©ν„°λ¦¬ λ©”μ„œλ“œ
    // λ°˜ν™˜ νƒ€μž…μ€ Shapeμ΄μ§€λ§Œ, μ‹€μ œλ‘œλŠ” Circle μΈμŠ€ν„΄μŠ€λ₯Ό λ°˜ν™˜
    static Shape circle(double radius) {
        return new Circle(radius); // Circle은 외뢀에 κ³΅κ°œλ˜μ§€ μ•Šμ€ package-private 클래슀
    }

    // μ‹€μ œλ‘œλŠ” Rect μΈμŠ€ν„΄μŠ€λ₯Ό λ°˜ν™˜
    static Shape rectangle(double width, double height) {
        return Rect.of(width, height); // 캐싱 κΈ°λŠ₯이 μžˆλŠ” 정적 νŒ©ν„°λ¦¬
    }
}

// Circle.java - λ‚΄λΆ€ κ΅¬ν˜„μ²΄ (package-private)
final class Circle implements Shape {
    private final double radius;

    // μƒμ„±μžλŠ” package-private으둜 μ™ΈλΆ€μ—μ„œ 직접 생성 λΆˆκ°€
    Circle(double radius) { this.radius = radius; }

    @Override
    public double area() { return Math.PI * radius * radius; }
}

// Rect.java - λ‚΄λΆ€ κ΅¬ν˜„μ²΄ (package-private)
final class Rect implements Shape {
    private static final Map<String, Rect> CACHE = new HashMap<>();
    private final double width, height;

    private Rect(double width, double height) { this.width = width; this.height = height; }

    // 정적 νŒ©ν„°λ¦¬ + 캐싱 (ν”ŒλΌμ΄μ›¨μ΄νŠΈ νŒ¨ν„΄)
    static Rect of(double width, double height) {
        String key = width + "x" + height;
        return CACHE.computeIfAbsent(key, k -> new Rect(width, height));
    }

    @Override
    public double area() { return width * height; }
}

ν΄λΌμ΄μ–ΈνŠΈλŠ” Circleμ΄λ‚˜ Rect 클래슀의 쑴재λ₯Ό μ „ν˜€ λͺ¨λ₯Έ 채 Shape.circle(10)κ³Ό 같이 μΈν„°νŽ˜μ΄μŠ€λ§ŒμœΌλ‘œ 객체λ₯Ό μ‚¬μš©ν•˜κ²Œ λ©λ‹ˆλ‹€.

 

1-4. μž…λ ₯ λ§€κ°œλ³€μˆ˜μ— 따라 맀번 λ‹€λ₯Έ 클래슀의 객체λ₯Ό λ°˜ν™˜ν•  수 μžˆλ‹€.

3번 μž₯점의 μ—°μž₯μ„ μœΌλ‘œ, 정적 νŒ©ν„°λ¦¬ λ©”μ„œλ“œλŠ” μž…λ ₯값에 따라 λ°˜ν™˜ν•  객체의 클래슀λ₯Ό λ™μ μœΌλ‘œ κ²°μ •ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

EnumSet ν΄λž˜μŠ€κ°€ λŒ€ν‘œμ μΈ μ˜ˆμž…λ‹ˆλ‹€. EnumSet은 public μƒμ„±μž 없이 였직 정적 νŒ©ν„°λ¦¬ λ©”μ„œλ“œλ§Œ μ œκ³΅ν•©λ‹ˆλ‹€.

public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) {
    Enum<?>[] universe = getUniverse(elementType);
    if (universe == null)
        throw new ClassCastException(elementType + " not an enum");
    
    // μ›μ†Œμ˜ κ°œμˆ˜μ— 따라 λ‹€λ₯Έ κ΅¬ν˜„μ²΄λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.
    if (universe.length <= 64)
        return new RegularEnumSet<>(elementType, universe); // 64개 μ΄ν•˜λ©΄ long λ³€μˆ˜ ν•˜λ‚˜λ‘œ 관리
    else
        return new JumboEnumSet<>(elementType, universe);   // 65개 이상이면 long λ°°μ—΄λ‘œ 관리
}

ν΄λΌμ΄μ–ΈνŠΈλŠ” λ‚΄λΆ€μ μœΌλ‘œ RegularEnumSet이 μ“°μ΄λŠ”μ§€ JumboEnumSet이 μ“°μ΄λŠ”μ§€ μ „ν˜€ μ•Œ ν•„μš”κ°€ μ—†μŠ΅λ‹ˆλ‹€. κ·Έμ € EnumSet μΈν„°νŽ˜μ΄μŠ€λ‘œλ§Œ 닀루면 λ©λ‹ˆλ‹€. λ§Œμ•½ λ‚˜μ€‘μ— RegularEnumSet의 μ„±λŠ₯상 이점이 사라져, JDK νŒ€μ΄ ν•΄λ‹Ή 클래슀λ₯Ό μ‚­μ œν•˜κ³  항상 JumboEnumSet만 λ°˜ν™˜ν•˜λ„λ‘ μ½”λ“œλ₯Ό μˆ˜μ •ν•œλ‹€ 해도 ν΄λΌμ΄μ–ΈνŠΈμ—κ²ŒλŠ” μ•„λ¬΄λŸ° 영ν–₯이 μ—†μŠ΅λ‹ˆλ‹€.

1-5. 정적 νŒ©ν„°λ¦¬ λ©”μ„œλ“œλ₯Ό μž‘μ„±ν•˜λŠ” μ‹œμ μ—λŠ” λ°˜ν™˜ν•  객체의 ν΄λž˜μŠ€κ°€ μ‘΄μž¬ν•˜μ§€ μ•Šμ•„λ„ λœλ‹€.

이 μœ μ—°ν•¨μ€ μ„œλΉ„μŠ€ 제곡자 ν”„λ ˆμž„μ›Œν¬(Service Provider Framework)λ₯Ό λ§Œλ“œλŠ” 근간이 λ©λ‹ˆλ‹€.

λŒ€ν‘œμ μΈ μ˜ˆλŠ” JDBC(Java Database Connectivity)μž…λ‹ˆλ‹€.

μ„œλΉ„μŠ€ 제곡자 ν”„λ ˆμž„μ›Œν¬μ˜ 핡심은 μ„œλΉ„μŠ€μ˜ κ΅¬ν˜„μ²΄μ™€ ν΄λΌμ΄μ–ΈνŠΈλ₯Ό λΆ„λ¦¬ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.

  1. μ„œλΉ„μŠ€ μΈν„°νŽ˜μ΄μŠ€: κ΅¬ν˜„μ²΄μ˜ λ™μž‘μ„ μ •μ˜ (JDBC의 Connection)
  2. 제곡자 등둝 API: μ œκ³΅μžκ°€ μžμ‹ μ˜ κ΅¬ν˜„μ²΄λ₯Ό 등둝 (DriverManager.registerDriver)
  3. μ„œλΉ„μŠ€ μ ‘κ·Ό API: ν΄λΌμ΄μ–ΈνŠΈκ°€ μ„œλΉ„μŠ€ μΈμŠ€ν„΄μŠ€λ₯Ό μ–»λŠ” API. 정적 νŒ©ν„°λ¦¬ λ©”μ„œλ“œ. (DriverManager.getConnection)
  4. μ„œλΉ„μŠ€ 제곡자 μΈν„°νŽ˜μ΄μŠ€: κ΅¬ν˜„μ²΄λ₯Ό μƒμ„±ν•˜λŠ” νŒ©ν„°λ¦¬ 객체λ₯Ό μ„€λͺ… (Driver)

ν΄λΌμ΄μ–ΈνŠΈλŠ” μ„œλΉ„μŠ€ μ ‘κ·Ό API(DriverManager.getConnection)λ₯Ό ν˜ΈμΆœν•  λ•Œ μ–΄λ–€ λ°μ΄ν„°λ² μ΄μŠ€(MySQL, Oracle λ“±)에 μ—°κ²°ν• μ§€ λͺ…μ‹œν•©λ‹ˆλ‹€. 그러면 ν”„λ ˆμž„μ›Œν¬λŠ” 미리 λ“±λ‘λœ 제곡자(MySQL Driver, Oracle Driver)λ₯Ό μ‚¬μš©ν•΄ ν•΄λ‹Ή Connection κ΅¬ν˜„μ²΄ μΈμŠ€ν„΄μŠ€λ₯Ό λ§Œλ“€μ–΄ λ°˜ν™˜ν•©λ‹ˆλ‹€.

이 ꡬ쑰 덕뢄에 DriverManager μ½”λ“œλ₯Ό μž‘μ„±ν•˜λŠ” μ‹œμ μ—λŠ” 세상에 μ–΄λ–€ Driver κ΅¬ν˜„μ²΄κ°€ μ‘΄μž¬ν• μ§€ μ „ν˜€ μ•Œ ν•„μš”κ°€ μ—†μŠ΅λ‹ˆλ‹€. 이것이 λ°”λ‘œ "ν΄λž˜μŠ€κ°€ μ‘΄μž¬ν•˜μ§€ μ•Šμ•„λ„ λœλ‹€"λŠ” 말의 μ˜λ―Έμž…λ‹ˆλ‹€.

2. 정적 νŒ©ν„°λ¦¬ λ©”μ„œλ“œ μ‚¬μš©μ˜ 단점

λ¬Όλ‘  μž₯점만 μžˆλŠ” 것은 μ•„λ‹™λ‹ˆλ‹€. λ‹€μŒκ³Ό 같은 단점도 μ‘΄μž¬ν•©λ‹ˆλ‹€.

2-1. 상속을 ν•˜λ €λ©΄ publicμ΄λ‚˜ protected μƒμ„±μžκ°€ ν•„μš”ν•˜λ‹ˆ μ •μ νŒ©ν„°λ¦¬λ§Œ μ œκ³΅ν•˜λ©΄ ν•˜μœ„ 클래슀λ₯Ό λ§Œλ“€ 수 μ—†λ‹€.

Collections의 μœ ν‹Έλ¦¬ν‹° κ΅¬ν˜„ ν΄λž˜μŠ€λ“€μ΄ 상속될 수 없도둝 μ„€κ³„λœ 것이 λ°”λ‘œ 이 λ•Œλ¬Έμž…λ‹ˆλ‹€. ν•˜μ§€λ§Œ μ΄λŠ” 였히렀 상속보닀 μ»΄ν¬μ§€μ…˜μ„ μ‚¬μš©ν•˜λ„λ‘ μœ λ„ν•˜κ³ , λΆˆλ³€(Immutable) νƒ€μž…μœΌλ‘œ μ„€κ³„ν•˜κΈ° μ‰½κ²Œ λ§Œλ“ λ‹€λŠ” μ μ—μ„œ μž₯점으둜 μž‘μš©ν•˜κΈ°λ„ ν•©λ‹ˆλ‹€.

2-2. 정적 νŒ©ν„°λ¦¬ λ©”μ„œλ“œλŠ” ν”„λ‘œκ·Έλž˜λ¨Έκ°€ μ°ΎκΈ° μ–΄λ ΅λ‹€. 

μƒμ„±μžλŠ” API λ¬Έμ„œ 상단에 λͺ…ν™•ν•˜κ²Œ λͺ¨μ—¬μžˆμ§€λ§Œ, 정적 νŒ©ν„°λ¦¬ λ©”μ„œλ“œλŠ” λ‹€λ₯Έ 일반적인 λ©”μ„œλ“œλ“€ 사이에 μ„žμ—¬ μžˆμ–΄ λˆˆμ— 잘 띄지 μ•Šμ„ 수 μžˆμŠ΅λ‹ˆλ‹€.

이 단점을 μ™„ν™”ν•˜κΈ° μœ„ν•΄, API λ¬Έμ„œλ₯Ό μΆ©μ‹€νžˆ μž‘μ„±ν•˜κ³  널리 μ•Œλ €μ§„ λͺ…λͺ… κ·œμΉ™μ„ λ”°λ₯΄λŠ” 것이 맀우 μ€‘μš”ν•©λ‹ˆλ‹€.

 

πŸ’‘ 정적 νŒ©ν„°λ¦¬ λ©”μ„œλ“œ λͺ…λͺ… κ·œμΉ™

  • from: λ§€κ°œλ³€μˆ˜ ν•˜λ‚˜λ₯Ό λ°›μ•„ ν•΄λ‹Ή νƒ€μž…μ˜ μΈμŠ€ν„΄μŠ€λ₯Ό λ°˜ν™˜ (ν˜•λ³€ν™˜)
    • Date d = Date.from(instant);
  • of: μ—¬λŸ¬ λ§€κ°œλ³€μˆ˜λ₯Ό λ°›μ•„ μΈμŠ€ν„΄μŠ€λ₯Ό 생성 (집계)
    • Set<Rank> cards = EnumSet.of(JACK, QUEEN, KING);
  • valueOf: fromκ³Ό of의 더 μžμ„Έν•œ 버전
    • BigInteger prime = BigInteger.valueOf(Integer.MAX_VALUE);
  • instance, getInstance: μΈμŠ€ν„΄μŠ€λ₯Ό λ°˜ν™˜. 이미 μƒμ„±λœ 것을 λ°˜ν™˜ν•  μˆ˜λ„ 있음 (μ‹±κΈ€ν„΄)
    • StackWalker luke = StackWalker.getInstance(options);
  • create, newInstance: 맀번 μƒˆλ‘œμš΄ μΈμŠ€ν„΄μŠ€λ₯Ό μƒμ„±ν•˜μ—¬ λ°˜ν™˜ν•¨μ„ 보μž₯
    • Object newArr = Array.newInstance(classObject, arrayLen);
  • getType: λ‹€λ₯Έ ν΄λž˜μŠ€μ— νŒ©ν„°λ¦¬ λ©”μ„œλ“œλ₯Ό μ •μ˜ν•  λ•Œ μ‚¬μš©. getInstance와 μœ μ‚¬.
    • FileStore fs = Files.getFileStore(path);
  • newType: λ‹€λ₯Έ ν΄λž˜μŠ€μ— νŒ©ν„°λ¦¬ λ©”μ„œλ“œλ₯Ό μ •μ˜ν•  λ•Œ μ‚¬μš©. newInstance와 μœ μ‚¬.
    • BufferedReader br = Files.newBufferedReader(path);

정리

정적 νŒ©ν„°λ¦¬ λ©”μ„œλ“œμ™€ public μƒμ„±μžλŠ” 각자의 μ“°μž„μƒˆκ°€ μžˆμœΌλ‹ˆ, μƒλŒ€μ μΈ μž₯단점을 μ΄ν•΄ν•˜κ³  μ‚¬μš©ν•˜λŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€. ν•˜μ§€λ§Œ λ§Žμ€ 경우 정적 νŒ©ν„°λ¦¬ λ©”μ„œλ“œκ°€ 더 λ‚˜μ€ 선택이 될 수 μžˆμœΌλ―€λ‘œ, λ¬΄μž‘μ • public μƒμ„±μžλ₯Ό μ‚¬μš©ν•˜λŠ” 것은 μ§€μ–‘ν•˜λŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€.

728x90