Singleton Pattern이란? 

▶클래스가 한 개의 인스턴스만을 만들 수 있도록 하고, 어디서나 생성된 인스턴스에 접근할 수 있도록 합니다.

 

여러가지 방법으로 Singleton Pattern을 제작하므로 클래스 다이어그램은 생략하겠습니다. SingletonCalculator는 singleton으로 설계되었으며 더하기 연산과 빼기 연산을 수행합니다. 


1. static 메소드/ static 변수

public class SingletonCalculator {

    public static SingletonCalculator calculator = null;

    private SingletonCalculator() {
    }

    public SingletonCalculator getCalculator() {
        if (calculator == null) {
            calculator = new SingletonCalculator();
        }
        return calculator;
    }

    public double add(double n1, double n2) {
        return n1 + n2;
    }

    public double minus(double n1, double n2) {
        return n1 - n2;
    }
}

 

▶ 디폴트 생성자를 private로 막아 무분별한 사용을 막고 getCalculator()를 사용해서만 객체를 반환할 수 있습니다. 이때 문제점이 있습니다. 멀티 쓰레드 환경이라면 여러개의 객체가 생성될 수 있기 때문입니다. 

 

2. static 변수 활용

public class SingletonCalculator {

    public static SingletonCalculator calculator = new SingletonCalculator();

    private SingletonCalculator() {
    }

    public static SingletonCalculator getCalculator() {
        return calculator;
    }

    public double add(double n1, double n2) {
        return n1 + n2;
    }

    public double minus(double n1, double n2) {
        return n1 - n2;
    }
}

▶ static 변수는 객체가 생성되기 전 클래스가 메모리에 로딩 될 때 만들어져 초기화가 한 번만 되는 것을 이용하는 것이다. 

 

3. synchronized를 통한 메소드 동기화

public class SingletonCalculator {

    public static SingletonCalculator calculator = null;

    private SingletonCalculator() {}

    public static synchronized SingletonCalculator getCalculator() {
        if (calculator == null) {
            calculator = new SingletonCalculator();
        }
        return calculator;
    }

    public double add(double n1, double n2) {
        return n1 + n2;
    }

    public double minus(double n1, double n2) {
        return n1 - n2;
    }
}

▶ synchronized를 메소드에 붙이면 해당 메소드가 임계구역으로 바뀌어 어떠한 쓰레드가 메소드를 사용하면 다른 쓰레드가 사용하지 못하게 Lock을 건다. 하지만 이 방식은 Lock을 사용하므로 속도 측면에서 느리다. 따라서 저는 2번 방법을 사용할 것 같습니다. 

 

4. Main class

public class Main {
    public static void main(String[] args) {
        SingletonCalculator calculator = SingletonCalculator.getCalculator();
        double result1 = calculator.add(1, 2);
        double result2 = calculator.minus(3, 4);

        System.out.println(result1);
        System.out.println(result2);

    }
}

// 출력 결과
// 3.0
// -1.0

 

Singleton Pattern은 많은 프레임워크에서 사용되는 방식입니다. Spring에서 bean을 사용하는 방법이기도 합니다. 지금까지 Singleton Pattern을 알아봤습니다. 감사합니다.

 

전체 코드는 아래에서 확인 가능합니다:)

https://github.com/rlaehdals/design-pattern

 

GitHub - rlaehdals/design-pattern

Contribute to rlaehdals/design-pattern development by creating an account on GitHub.

github.com

 

아래에서 다른 예제도 풀어보실 수 있습니다. 

https://github.com/rlaehdals/design-pattern/tree/master/singleton/%EC%98%88%EC%A0%9C

 

GitHub - rlaehdals/design-pattern

Contribute to rlaehdals/design-pattern development by creating an account on GitHub.

github.com