Design Patterns - low-hill/Knowledge GitHub Wiki

Singleton Pattern

싱글톀 λ””μžμΈ νŒ¨ν„΄λŠ” ν΄λž˜μŠ€κ°€ ν•˜λ‚˜μ˜ μΈμŠ€ν„΄μŠ€λ§Œ 가지도둝 ν•˜κ³  μ—¬λŸ¬ 번 호좜이 λ˜λ”λΌλ„ μΈμŠ€ν„΄μŠ€λ₯Ό μƒˆλ‘œ μƒμ„±ν•˜μ§€ μ•Šκ³  졜초 호좜 μ‹œμ— λ§Œλ“€μ–΄λ‘μ—ˆλ˜ μΈμŠ€ν„΄μŠ€λ₯Ό μž¬ν™œμš©ν•˜λŠ” νŒ¨ν„΄μ΄λ‹€. 싱글톀 λ””μžμΈ νŒ¨ν„΄λŠ” μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ—μ„œ ν”„λ‘œκ·Έλž¨ μ „μ²΄μ—μ„œ μ‚¬μš©λ˜λŠ” ꡬ성 μ„€μ •, λ°μ΄ν„°λ² μ΄μŠ€ 컀λ„₯μ…˜ ν’€ λ˜λŠ” 둜거 관리와 같이 클래슀의 μΈμŠ€ν„΄μŠ€ 수λ₯Ό ν•˜λ‚˜λ‘œ μ œν•œν•˜λ €λŠ” κ²½μš°μ— 자주 μ‚¬μš©λœλ‹€.

  • 싱글톀 νŒ¨ν„΄μ„ μ‚¬μš©ν•˜λ©΄ λ¦¬μ†ŒμŠ€λ₯Ό 효율적으둜 관리할 수 μžˆλ‹€.

    • 예λ₯Ό λ“€μ–΄ λ°μ΄ν„°λ² μ΄μŠ€ 컀λ„₯μ…˜ 풀을 ν•˜λ‚˜μ˜ μΈμŠ€ν„΄μŠ€λ‘œ μ œν•œν•˜μ—¬ λ§Žμ€ 수의 λ°μ΄ν„°λ² μ΄μŠ€ 연결을 생성을 λ°©μ§€
  • 싱글톀 νŒ¨ν„΄μ„ μ˜¬λ°”λ₯΄κ²Œ κ΅¬ν˜„ν•˜λ©΄ ν•˜λ‚˜μ˜ μΈμŠ€ν„΄μŠ€λ§Œ μƒμ„±λ˜λ„λ‘ ν•¨μœΌλ‘œμ¨ μŠ€λ ˆλ“œ μ•ˆμ „μ„±μ„ μ œκ³΅ν•  수 μžˆλ‹€.

    • μ΄λŠ” λ©€ν‹°μŠ€λ ˆλ“œ ν™˜κ²½μ—μ„œ κ²½μŸμ„ λ°©μ§€ν•˜κ³  μ μ ˆν•œ 동기화λ₯Ό 보μž₯ν•˜κΈ° μœ„ν•΄ 맀우 μ€‘μš”
public class ConfigurationManager {
    
    private static ConfigurationManager instance;

    private String databaseUrl;
    private int maxConnections;

    // Private constructor to prevent creating multiple instances
    private ConfigurationManager() {
        this.databaseUrl = "jdbc:mysql://localhost:3306/mydatabase";
        this.maxConnections = 10;
    }

    // Method to get the one and only instance of ConfigurationManager
    public static ConfigurationManager getInstance() {
        if (instance == null) {
            instance = new ConfigurationManager(); // Create the instance if it doesn't exist yet
        }
        return instance;
    }

    // Getter methods for configuration settings
    public String getDatabaseUrl() {
        return databaseUrl;
    }

    public int getMaxConnections() {
        return maxConnections;
    }

    public void setMaxConnections(int maxConnections) {
        this.maxConnections = maxConnections;
    }
}

Factory Design Pattern

νŒ©ν† λ¦¬ νŒ¨ν„΄μ€ 객체 μƒμ„±μ˜ 과정을 μΆ”μƒν™”ν•˜λŠ” μƒμ„±ν˜• λ””μžμΈ νŒ¨ν„΄μž…λ‹ˆλ‹€. 이 νŒ¨ν„΄μ€ 객체λ₯Ό 생성할 λ•Œ, 객체의 ꡬ체적인 νƒ€μž…μ„ λͺ…μ‹œν•˜μ§€ μ•Šκ³ , μ„œλΈŒν΄λž˜μŠ€λ‚˜ μ „λ¬Έν™”λœ νŒ©ν† λ¦¬ ν΄λž˜μŠ€μ— 객체 생성 μ±…μž„μ„ μœ„μž„ν•©λ‹ˆλ‹€. μ΄λŸ¬ν•œ μΆ”μƒν™”λŠ” μ½”λ“œμ˜ μœ μ—°μ„±κ³Ό μœ μ§€λ³΄μˆ˜μ„±μ„ λ†’μ—¬μ€λ‹ˆλ‹€.

νŒ©ν† λ¦¬ λ””μžμΈ νŒ¨ν„΄μ˜ ꡬ성 μš”μ†Œ

νŒ©ν† λ¦¬ λ””μžμΈ νŒ¨ν„΄μ„ κ΅¬ν˜„ν•˜κΈ° 전에 νŒ¨ν„΄μ„ κ΅¬μ„±ν•˜λŠ” μ£Όμš” μš”μ†Œλ“€μ— λŒ€ν•΄ μ΄ν•΄ν•©λ‹ˆλ‹€. 각 ꡬ성 μš”μ†ŒλŠ” 객체 생성 과정을 λΆ„λ¦¬ν•˜μ—¬ μœ μ—°μ„±κ³Ό ν™•μž₯성을 μ œκ³΅ν•˜λŠ”λ° μ€‘μš”ν•œ 역할을 ν•©λ‹ˆλ‹€. μ•„λž˜λŠ” νŒ©ν† λ¦¬ νŒ¨ν„΄μ˜ 핡심 ꡬ성 μš”μ†Œλ“€μž…λ‹ˆλ‹€:

  1. Product (μ œν’ˆ)
    ProductλŠ” 생성할 객체의 νƒ€μž…μ„ μ •μ˜ν•˜λŠ” μΈν„°νŽ˜μ΄μŠ€ λ˜λŠ” 좔상 ν΄λž˜μŠ€μž…λ‹ˆλ‹€. 이 μš”μ†ŒλŠ” νŒ©ν† λ¦¬κ°€ 생성해야 ν•  객체듀이 κ°€μ Έμ•Ό ν•  곡톡적인 μ†μ„±μ΄λ‚˜ λ©”μ„œλ“œλ₯Ό μ„ μ–Έν•©λ‹ˆλ‹€. μ‹€μ œ 객체듀이 이 μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•˜κ±°λ‚˜, 좔상 클래슀λ₯Ό ν™•μž₯ν•˜μ—¬ κ΅¬μ²΄ν™”λ©λ‹ˆλ‹€.

  2. Concrete Product (ꡬ체적인 μ œν’ˆ)
    Concrete ProductλŠ” Product μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•˜κ±°λ‚˜ Product 좔상 클래슀λ₯Ό μƒμ†λ°›λŠ” μ‹€μ œ ν΄λž˜μŠ€λ“€μž…λ‹ˆλ‹€. 이듀은 νŒ©ν† λ¦¬κ°€ μƒμ„±ν•˜λŠ” μ‹€μ œ κ°μ²΄λ“€λ‘œ, νŠΉμ •ν•œ κΈ°λŠ₯을 μˆ˜ν–‰ν•˜λŠ” μΈμŠ€ν„΄μŠ€λ₯Ό μ œκ³΅ν•©λ‹ˆλ‹€. 즉, νŒ©ν† λ¦¬ νŒ¨ν„΄μ—μ„œ μ •μ˜λœ 'μ œν’ˆ'이 ꡬ체적인 ν˜•νƒœλ‘œ λ‚˜νƒ€λ‚˜λŠ” ν΄λž˜μŠ€λ“€μž…λ‹ˆλ‹€.

  3. Factory (νŒ©ν† λ¦¬)
    FactoryλŠ” 객체λ₯Ό μƒμ„±ν•˜λŠ” νŒ©ν† λ¦¬ λ©”μ„œλ“œλ₯Ό μ„ μ–Έν•˜λŠ” μΈν„°νŽ˜μ΄μŠ€ λ˜λŠ” 좔상 ν΄λž˜μŠ€μž…λ‹ˆλ‹€. νŒ©ν† λ¦¬μ˜ μ£Όμš” 역할은 객체 생성을 μΆ”μƒν™”ν•˜μ—¬, μ‹€μ œ 객체 생성 방법에 λŒ€ν•œ μ„ΈλΆ€ κ΅¬ν˜„μ„ μ™ΈλΆ€μ—μ„œ 숨기고, 객체λ₯Ό 효율적으둜 생성할 수 μžˆλŠ” λ©”μ„œλ“œλ₯Ό μ œκ³΅ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.

  4. Concrete Factory (ꡬ체적인 νŒ©ν† λ¦¬)
    Concrete FactoryλŠ” Factory μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•˜κ±°λ‚˜ Factory 좔상 클래슀λ₯Ό μƒμ†λ°›λŠ” ꡬ체적인 ν΄λž˜μŠ€μž…λ‹ˆλ‹€. 이 ν΄λž˜μŠ€λŠ” νŒ©ν† λ¦¬ λ©”μ„œλ“œλ₯Ό κ΅¬ν˜„ν•˜μ—¬, νŠΉμ •ν•œ μ’…λ₯˜μ˜ Product 객체λ₯Ό μƒμ„±ν•˜λŠ” 역할을 ν•©λ‹ˆλ‹€. 각 Concrete FactoryλŠ” νŠΉμ • Product μœ ν˜•μ„ μƒμ„±ν•˜λŠ” 방법을 μ •μ˜ν•˜λ©°, 이둜써 λ‹€μ–‘ν•œ μ’…λ₯˜μ˜ 객체듀을 μœ μ—°ν•˜κ²Œ 생성할 수 μžˆλ„λ‘ ν•©λ‹ˆλ‹€.

νŒ©ν† λ¦¬ λ””μžμΈ νŒ¨ν„΄μ˜ μž₯단점 뢄석

μ£Όμš” μž₯점:

νŒ©ν† λ¦¬ νŒ¨ν„΄μ€ 객체 생성 λ‘œμ§μ„ μ€‘μ•™ν™”ν•˜μ—¬ μ½”λ“œμ˜ μœ μ§€λ³΄μˆ˜μ„±μ„ 높이고, μƒˆλ‘œμš΄ 객체λ₯Ό μΆ”κ°€ν•  λ•Œ κΈ°μ‘΄ μ½”λ“œλ₯Ό λ³€κ²½ν•˜μ§€ μ•Šμ•„λ„ λ˜λŠ” μž₯점이 μžˆμŠ΅λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ νŒ¨ν„΄μ˜ μ‚¬μš©μ΄ λΆˆν•„μš”ν•˜κ²Œ λ³΅μž‘μ„±μ„ μ΄ˆλž˜ν•  수 있으며, ν΄λΌμ΄μ–ΈνŠΈκ°€ νŒ©ν† λ¦¬μ— μ˜μ‘΄ν•˜κ²Œ λ˜λŠ” 단점도 μ‘΄μž¬ν•©λ‹ˆλ‹€. λ”°λΌμ„œ 객체 생성이 λ³΅μž‘ν•˜κ±°λ‚˜ λ‹€μ–‘ν•œ ν˜•νƒœλ₯Ό κ°€μ§ˆ λ•Œ μœ μš©ν•˜κ²Œ μ‚¬μš©ν•  수 있으며, μ μ ˆν•œ μƒν™©μ—μ„œλ§Œ μ μš©ν•˜λŠ” 것이 μ€‘μš”ν•©λ‹ˆλ‹€.

  1. 객체 μƒμ„±μ˜ 결합도 κ°μ†Œ: ν΄λΌμ΄μ–ΈνŠΈλŠ” ν•„μš”ν•œ 객체의 ꡬ체적인 ν΄λž˜μŠ€μ— λŒ€ν•΄ μ•Œ ν•„μš”κ°€ μ—†μŠ΅λ‹ˆλ‹€. ν΄λΌμ΄μ–ΈνŠΈλŠ” νŒ©ν† λ¦¬ λ©”μ„œλ“œλ₯Ό 톡해 객체λ₯Ό μš”μ²­ν•˜κ³ , νŒ©ν† λ¦¬λŠ” μ μ ˆν•œ 객체λ₯Ό μƒμ„±ν•˜μ—¬ λ°˜ν™˜ν•©λ‹ˆλ‹€.

  2. μœ μ§€λ³΄μˆ˜μ„± ν–₯상: 객체 생성 둜직이 νŒ©ν† λ¦¬μ— μ§‘μ€‘λ˜μ–΄ 있기 λ•Œλ¬Έμ— 객체 생성 방식에 변경이 ν•„μš”ν•  경우, ν•΄λ‹Ή νŒ©ν† λ¦¬ λ‚΄μ—μ„œλ§Œ μˆ˜μ •ν•˜λ©΄ λ©λ‹ˆλ‹€. 이둜 인해 ν΄λΌμ΄μ–ΈνŠΈ μ½”λ“œλ‚˜ λ‹€λ₯Έ μ‹œμŠ€ν…œ 뢀뢄에 영ν–₯을 μ£Όμ§€ μ•Šκ²Œ λ©λ‹ˆλ‹€.

  3. 변경에 λŒ€ν•œ μœ μ—°μ„± 증가: νŒ©ν† λ¦¬ νŒ¨ν„΄μ€ μƒˆλ‘œμš΄ 객체 νƒ€μž…μ„ μΆ”κ°€ν•  λ•Œ μœ λ¦¬ν•©λ‹ˆλ‹€. μƒˆλ‘œμš΄ 객체 μœ ν˜•(ꡬ체적인 μ œν’ˆ)을 μΆ”κ°€ν•  λ•Œ κΈ°μ‘΄ μ½”λ“œλ₯Ό λ³€κ²½ν•˜μ§€ μ•Šκ³  μƒˆλ‘œμš΄ νŒ©ν† λ¦¬λ₯Ό μΆ”κ°€ν•˜λŠ” λ°©μ‹μœΌλ‘œ ν•΄κ²°ν•  수 μžˆμŠ΅λ‹ˆλ‹€. μ΄λŠ” μ½”λ“œμ˜ ν™•μž₯성을 높이고, μƒˆλ‘œμš΄ μš”κ΅¬μ‚¬ν•­μ— μœ μ—°ν•˜κ²Œ λŒ€μ‘ν•  수 있게 ν•©λ‹ˆλ‹€.

  4. μΌκ΄€λœ 객체 생성 보μž₯
    νŒ©ν† λ¦¬ νŒ¨ν„΄μ€ κ³΅ν†΅λœ μΈν„°νŽ˜μ΄μŠ€(Product)λ₯Ό 톡해 객체 생성 κ·œμΉ™μ„ κ°•μ œν•©λ‹ˆλ‹€. 이 일관성은 μ½”λ“œ μœ μ§€λ³΄μˆ˜λ₯Ό μ‰½κ²Œ ν•˜κ³ , 였λ₯˜λ₯Ό μ΅œμ†Œν™”ν•˜λŠ” 데 κΈ°μ—¬ν•©λ‹ˆλ‹€.

단점

  1. 전체 μ½”λ“œλ² μ΄μŠ€ λ³΅μž‘λ„ 증가
    νŒ©ν† λ¦¬ νŒ¨ν„΄μ„ κ΅¬ν˜„ν•˜λ©΄ μ½”λ“œλ² μ΄μŠ€μ— μƒˆλ‘œμš΄ 좔상화 계측이 μΆ”κ°€λ©λ‹ˆλ‹€. μ΄λŠ” κ°œλ°œμžμ—κ²ŒλŠ” 좔가적인 ν•™μŠ΅ 뢀담을 쀄 수 있고, νŒ¨ν„΄μ„ 잘 μ΄ν•΄ν•˜μ§€ λͺ»ν•œ κ°œλ°œμžμ—κ²ŒλŠ” ν˜Όλž€μ„ μ•ΌκΈ°ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

  2. νŒ©ν† λ¦¬ λ‘œμ§μ— λŒ€ν•œ μ˜μ‘΄μ„±
    ν΄λΌμ΄μ–ΈνŠΈ μ½”λ“œκ°€ ꡬ체적인 μ œν’ˆ(Concrete Products)μ—μ„œ λΆ„λ¦¬λ˜κΈ°λŠ” ν•˜μ§€λ§Œ, μ—¬μ „νžˆ ꡬ체적인 νŒ©ν† λ¦¬(Concrete Factories)에 κ°•ν•˜κ²Œ μ˜μ‘΄ν•©λ‹ˆλ‹€. λ”°λΌμ„œ νŒ©ν† λ¦¬ λ‘œμ§μ— 큰 λ³€ν™”κ°€ μžˆμ„ 경우 μ—¬λŸ¬ λΆ€λΆ„μ—μ„œ 영ν–₯을 받을 수 μžˆμŠ΅λ‹ˆλ‹€.

  3. λ³΅μž‘ν•œ 객체 생성이 아닐 경우 μ˜€λ²„μ—”μ§€λ‹ˆμ–΄λ§
    객체 생성이 λ³΅μž‘ν•˜μ§€ μ•Šκ±°λ‚˜ 변동성이 적은 경우, νŒ©ν† λ¦¬ νŒ¨ν„΄μ„ μ μš©ν•˜λ©΄ 였히렀 λΆˆν•„μš”ν•œ λ³΅μž‘μ„±μ„ μ΄ˆλž˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 이 νŒ¨ν„΄μ€ 객체 생성 과정에 λ³€μˆ˜κ°€ λ§Žκ±°λ‚˜ λ³΅μž‘ν•  λ•Œ κ°€μž₯ νš¨κ³Όμ μž…λ‹ˆλ‹€.


Strategy Pattern

μ „λž΅ νŒ¨ν„΄μ€ νŠΉμ •ν•œ κ³„μ—΄μ˜ μ•Œκ³ λ¦¬μ¦˜(곡톡 μΈν„°νŽ˜μ΄μŠ€ λ˜λŠ” 좔상 클래슀λ₯Ό κ΅¬ν˜„ν•˜λŠ” ꡬ체적인 클래슀)을 μ •μ˜ν•˜κ³  각 μ•Œκ³ λ¦¬μ¦˜μ„ μΊ‘μŠν™”ν•˜κ³  μƒν˜Έ κ΅ν™˜ κ°€λŠ₯ν•˜κ²Œ λ§Œλ“œλŠ” ν–‰μœ„ μ†Œν”„νŠΈμ›¨μ–΄ λ””μžμΈ νŒ¨ν„΄μ΄λ‹€. μ•Œκ³ λ¦¬μ¦˜μ„ μ‚¬μš©ν•˜λŠ” μ»¨ν…μŠ€νŠΈ(context)​λ₯Ό λ³€κ²½ν•˜μ§€ μ•Šκ³ λ„ μ•Œκ³ λ¦¬μ¦˜μ˜ ν–‰μœ„λ₯Ό λ³€κ²½ν•  수 μžˆλ‹€. 이 νŒ¨ν„΄μ€ μ»¨ν…μŠ€νŠΈμ™€ μ „λž΅ 객체 κ°„μ˜ λŠμŠ¨ν•œ 결합을 μ΄‰μ§„ν•˜μ—¬ μ½”λ“œλ₯Ό ν™•μž₯ κ°€λŠ₯ν•˜κ³  μœ μ§€λ³΄μˆ˜μ— μš©μ΄ν•˜λ„λ‘ ν•œλ‹€.

μ „λž΅ νŒ¨ν„΄μ—μ„œ μ»¨ν…μŠ€νŠΈμ™€ μ „λž΅ κ°μ²΄λŠ” 핡심 ꡬ성 μš”μ†Œ

  • μ»¨ν…μŠ€νŠΈ(Context)
    • μ „λž΅μ„ μ‚¬μš©ν•˜λŠ” ν΄λΌμ΄μ–ΈνŠΈ κ°μ²΄μž…λ‹ˆλ‹€. 이 κ°μ²΄λŠ” μ „λž΅μ„ μ„€μ •ν•˜κ³  μ‹€ν–‰ν•˜λŠ” 역할을 ν•©λ‹ˆλ‹€.
  • Strategy
    • μ•Œκ³ λ¦¬μ¦˜(ν–‰μœ„)을 μ •μ˜ν•˜λŠ” μΈν„°νŽ˜μ΄μŠ€μž…λ‹ˆλ‹€. μ—¬λŸ¬ κ°€μ§€ μ•Œκ³ λ¦¬μ¦˜μ΄ 이 μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•˜μ—¬ μ œκ³΅λ©λ‹ˆλ‹€.
  • ConcreteStrategy
    • Strategy μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•œ ꡬ체적인 μ•Œκ³ λ¦¬μ¦˜(ν–‰μœ„)을 μ œκ³΅ν•©λ‹ˆλ‹€.

μ „λž΅ νŒ¨ν„΄ μž₯점

  • μ•Œκ³ λ¦¬μ¦˜ ꡐ체
    • μ „λž΅ νŒ¨ν„΄μ„ μ‚¬μš©ν•˜λ©΄ ν΄λΌμ΄μ–ΈνŠΈκ°€ μ•Œκ³ λ¦¬μ¦˜μ„ μ‹€ν–‰ν•  λ•Œλ§ˆλ‹€, ν•„μš”μ— 따라 λ‹€μ–‘ν•œ μ•Œκ³ λ¦¬μ¦˜μ„ μ‰½κ²Œ λ°”κΏ€ 수 μžˆμŠ΅λ‹ˆλ‹€.
  • ν΄λΌμ΄μ–ΈνŠΈ μ½”λ“œμ™€ μ•Œκ³ λ¦¬μ¦˜μ˜ 뢄리
    • μ•Œκ³ λ¦¬μ¦˜μ„ Strategy μΈν„°νŽ˜μ΄μŠ€λ₯Ό 톡해 μΊ‘μŠν™”ν•¨μœΌλ‘œμ¨ ν΄λΌμ΄μ–ΈνŠΈ μ½”λ“œμ—μ„œ μ•Œκ³ λ¦¬μ¦˜μ— λŒ€ν•œ μ„ΈλΆ€ κ΅¬ν˜„μ„ μ•Œ ν•„μš”κ°€ μ—†μ–΄μ§‘λ‹ˆλ‹€.
  • 개방-폐쇄 원칙
    • μƒˆλ‘œμš΄ μ•Œκ³ λ¦¬μ¦˜μ΄ μΆ”κ°€λ˜μ–΄λ„ κΈ°μ‘΄ μ½”λ“œλ₯Ό μˆ˜μ •ν•  ν•„μš” 없이 μƒˆλ‘œμš΄ ConcreteStrategyλ₯Ό μΆ”κ°€ν•˜κΈ°λ§Œ ν•˜λ©΄ λ©λ‹ˆλ‹€.

예제둜 μ•Œμ•„λ³΄λŠ” μ „λž΅ νŒ¨ν„΄

λ‹€μŒκ³Ό 같이 결제 μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ— μ „λž΅ λ””μžμΈ νŒ¨ν„΄μ„ μ‚¬μš©ν•˜μ—¬ 가독성 및 μœ μ—°μ„±μ„ ν–₯μƒμ‹œν‚€λŠ” 예λ₯Ό μ‚΄νŽ΄λ³Έλ‹€.
image

  • μ „λž΅(μΆ”μƒν™”λœ μ•Œκ³ λ¦¬μ¦˜/ν–‰μœ„) μ •μ˜
interface PaymentMethod {
    double calculateProcessingFee(double amount);
}
  • λ‹€μ–‘ν•œ ν–‰μœ„/μ•Œκ³ λ¦¬μ¦˜μ„ μ •μ˜ν•˜λŠ” ꡬ체적인 클래슀λ₯Ό μ •μ˜
@Component
class CreditCardPayment implements PaymentMethod {
    @Override
    public double calculateProcessingFee(double amount) {
        return amount * 0.01;
    }
}

@Component
class DebitCardPayment implements PaymentMethod {
    @Override
    public double calculateProcessingFee(double amount) {
        return amount * 0.02;
    }
}

@Component
class NetBankingPayment implements PaymentMethod {
    @Override
    public double calculateProcessingFee(double amount) {
        return amount * 0.005;
    }
}
  • μ»¨ν…μŠ€νŠΈ(μ „λž΅ μ‹€ν–‰)
@Service
@Slf4j
public class PaymentService {
    private final PaymentMethod creditCardPayment;
    private final PaymentMethod debitCardPayment;
    private final PaymentMethod netBankingPayment;
    private Map<String, PaymentMethod> paymentMethodsMap;

    PaymentService(PaymentMethod creditCardPayment, 
            PaymentMethod debitCardPayment, PaymentMethod netBankingPayment) {
        this.creditCardPayment = creditCardPayment;
        this.debitCardPayment = debitCardPayment;
        this.netBankingPayment = netBankingPayment;
    }

    @PostConstruct
    void init() {
        paymentMethodsMap = new HashMap<>();
        paymentMethodsMap.put("CreditCard", creditCardPayment);
        paymentMethodsMap.put("DebitCard", debitCardPayment);
        paymentMethodsMap.put("NetBanking", netBankingPayment);
    }

    public void processPayment(double amount, String paymentMethod) {
        log.info("Processed amount: {}", 
          paymentMethodsMap.get(paymentMethod)
                           .calculateProcessingFee(amount));
    }
}
  • ν΄λΌμ΄μ–ΈνŠΈ(μ „λž΅ ꡐ체/μ „λž΅ μ‹€ν–‰ κ²°κ³Ό μ–»μŒ)
@Component
class PaymentServiceClientRunner {

    private final PaymentService paymentService;

    public PaymentServiceClientRunner(PaymentService paymentService) {
        this.paymentService = paymentService;
    }

    public void executePayment() {
        // Process payment with amount 100.0 and payment method as "CreditCard"
        paymentService.processPayment(100.0, "CreditCard");
    }
}

Reference