Java 디자인 패턴-01.Singleton

(Java 디자인 패턴 스터디 모집 중 : https://github.com/bluedskim/javaDesignPatterns)

singleton 일러스트 (출처 : refactoring.guru : Singleton pattern)

해결하려는 문제

  1. 공유된 자원은 대체로 한정적이다. 이 자원을 무분별하게 사용하는 경우 쉽게 고갈될 수 있다.

용도

  1. 어플리케이션을 통틀어 한 개의 인스턴스만 필요할 때
  2. 그 한 개의 인스턴스를 쉽게 접근하고자 할 때
  3. 어플리케이션의 전체 영역에서 사용할 수 있는 전역변수가 필요할 때

특징

  1. 해당 클래스의 생성자는 직접 호출할 수 없음
  2. 대신 해당 객체를 반환하는 public static 메소드를 만든다

고려사항

  1. 객체지향 설계원칙에 위배
    • singleton 클래스는 상속 불가
  2. “No control over creation”
  3. singleton 클래스에 dependency injection 불가
  4. spring bean은 기본적으로 singleton으로 동작한다(https://www.baeldung.com/spring-bean-scopes)

클래스 다이어그램

Singleton 패턴(김동석)

소스

  • 소스 다운로드 : https://github.com/bluedskim/javaDesignPatterns/tree/master/01.Singleton/dskim_singleton

  • 싱글톤 클래스 : Coin.java

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    
    package net.dskim.desingpattern.singleton;
    
    public class Coin {
    	private static final int ADD_MORE_COIN = 10;
    	private int coinCount;
    	private static Coin instance = new Coin(); // Eagerly Loading of singleton instance
    
    	private Coin() {
    		// private to prevent anyone else from instantiating
    	}
    
    	public static Coin getInstance() {
    		return instance;
    	}
    
    	public int getCoinCount() {
    		return coinCount;
    	}
    
    	public void addMoreCoin() {
    		coinCount += ADD_MORE_COIN;
    	}
    
    	public void deductCoin() {
    		coinCount--;
    	}
    }

  • 클라이언트 : SingletonTest.java

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    
    package net.dskim.desingpattern.singleton;
    
    import static org.junit.jupiter.api.Assertions.assertEquals;
    
    import org.junit.jupiter.api.Test;
    
    import lombok.extern.slf4j.Slf4j;
    
    @Slf4j
    public class SingletonTest {
    	@Test
    	public void singletonTest() {
    		Coin coin1 = Coin.getInstance();
    		Coin coin2 = Coin.getInstance();
    
    		log.info("coin1={}, coin2={}", coin1, coin2);
    		assertEquals(coin1, coin2);
    
    		coin1.addMoreCoin();
    		
    		log.info("coin1.getCoinCount()={}, coin2.getCoinCount()={}", coin1.getCoinCount(), coin2.getCoinCount());
    		assertEquals(10, coin2.getCoinCount());
    
    		coin2.deductCoin();
    		log.info("coin1.getCoinCount()={}, coin2.getCoinCount()={}", coin1.getCoinCount(), coin2.getCoinCount());
    		assertEquals(9, coin1.getCoinCount());
    	}
    }

참고

(Java 디자인 패턴 스터디 모집 중 : https://github.com/bluedskim/javaDesignPatterns)