CS/디자인패턴

[디자인패턴] Singleton 패턴 (싱글톤)

mabb 2023. 5. 30. 17:43
반응형

▶디자인 패턴 ( Design Pattern)

:프로그램 개발 시 문제 해결을 위하여 빈번히 사용되는 개발자들의 경험, 내적인 축적에 대하여,
GoF(Gang of Four)라 불리는 4인의 개발자들이 각각을 패턴으로 정의하고 이름을 붙였다.
이를 디자인 패턴 (Design Pattern) 이라고 한다.
 23개의 디자인 패턴을
『Elements of Reusable Object-Oriented Software』
라는 책으로 발간하였다.

Gang of Four 분들은 모두 안경을 썼다.

 

▷디자인 패턴의 용어를 빌리면 서로의 아이디어를 보다 용이하게 비교, 논의할 수 있게 된다.
▷재사용과 기능확장이 쉬운 소프트웨어를 만들기 위한 유익한 기법이 바로 디자인 패턴이다.

 

---------------------------------------------------------
1. Iterator
2. Adapter
3. Template Method
4. Factory Method
5. Singleton
6. Prototype
7. Builder
8. Abstract Factory
9. Bridge
10. Strategy
11. Composite
12. Decorator
13. Visitor
14. Chain of Responsibility
15. Facade
16. Mediator
17. Observer
18. Memento
19. State
20. Flyweight
21. Proxy
22. Command
23. Interpreter
---------------------------------------------------------

▶Singleton 패턴

"하나뿐인 인스턴스"
"private 한 생성자, static메소드"


-왜 사용하는가
-클래스다이어그램
-각 클래스(인터페이스)의 역할
-Java소스

▶Singleton 패턴에 대한 이해

-클래스의 인스턴스가 딱 하나만 있어야 함을 보증하고자 할 때 사용하는 패턴을 싱글톤패턴이라고 한다.

-지정한 클래스의 인스턴스가 절대로 한 개만 있음을 보증하고자 한다.

-생성자를 private하게 만들어 외부에서 더 이상의 인스턴스 생성을 금지한다.

-생성자는 static 클래스 초기화 시 static필드를 초기화 할 때 '딱 한 번' 실행된다.

-싱글톤 클래스는 '딱 한 번' 만든 인스턴스를 반환하는 역할을 수행한다.

-static 메소드를 최초 호출했을 때 static 필드가 초기화되면서 유일한 인스턴스가 생성된다.

 

▶왜 사용하는가

해당 클래스의 인스턴스가 1개만 있음을 프로그램 상에서 표현하고 싶거나, 1개의 인스턴스만 생성되도록 보장하고자 할 때 사용한다.

 

▶클래스다이어그램

싱글톤패턴의 클래스다이어그램

 

▶각 클래스(인터페이스)의 역할

▷싱글톤 클래스
: 인스턴스를 한 개만 생성하는 것을 보증하는 클래스이다.

▷메인 클래스
: 싱글톤 클래스로 인스턴스를 생성하여 정말로 한 개만 만들어지는지 테스트한다.

 

▶Java 소스

*java1.8 이전 버전을 사용하는 교재를 참고하였습니다.
Java API 문서 등을 참조하여 제네릭을 적용하는 등 소스를 개선할 필요가 있습니다.
(https://docs.oracle.com/en/java/javase/20/docs/api/)

Main.java

package main.java.designpattern.singleton;

public class Main {

    public static void main(String[] args){

        System.out.println("메인스레드시작");
        System.out.println("싱글톤 생성 예제");


        ImSingleton is1 = ImSingleton.getSingleton();
        ImSingleton is2 = ImSingleton.getSingleton();

        // ImSingleton is3 = new ImSingleton();  // private하여 new 생성자 접근 불가

        System.out.println("is1 : " + is1.toString());
        System.out.println("is2 : " + is2.toString());


    }
}

 

 

ImSingleton.java

package main.java.designpattern.singleton;

public class ImSingleton {

    private static ImSingleton singleton = new ImSingleton();

    private ImSingleton(){
        System.out.println("싱글톤 인스턴스 생성!");
    }

    public static ImSingleton getSingleton(){
        return singleton;
    }

}

메인메소드 실행 시 콘솔 창

 

 

 

▷가짜 싱글톤 - 자바언어로 배우는 디자인 패턴 입문(영진닷컴)

NotSingleton.java

package main.java.designpattern.singleton;

public class NotSingleton {
    private static NotSingleton ns = null;

    private NotSingleton(){
        System.out.println("인스턴스가 생성되었습니다!");
    }

    public static NotSingleton getInstance(){
        if(ns == null){
            ns = new NotSingleton();
        }
        return ns;
    }
}

위의 소스는 엄밀하게는 싱글톤이 아니라고 한다.

MainEx2.java

package main.java.designpattern.singleton;

public class MainEx2 extends Thread {

    public MainEx2(String name){
        super(name);
    }

    public static void main(String[] args){
        System.out.println("Start");
        new MainEx2("A").start();
        new MainEx2("B").start();
        new MainEx2("C").start();
        System.out.println("End");
    }

    @Override
    public void run(){
        NotSingleton obj = NotSingleton.getInstance();
        System.out.println(getName() + ": obj = " + obj);
    }
}

 ThreadSafe가 아니기 때문에 멀티스레드에서는 인스턴스가 여러개 생겨버릴 수가 있는 것.

하지만 상단의 ImSingleton 은 같은 조건에서 여러개의 인스턴스가 생기지 않는다.

 

 

static메소드를 Synchronized 하게 만들어 준다면? 

public static synchronized NotSingleton getInstance(){
    if(ns == null){
        ns = new NotSingleton();
    }
    return ns;
}

 

해당 코드도 멀티스레드 환경에서 싱글톤임이 보장된다.

 

---------------------------------------------------------
※참고자료
-Java언어로 배우는 디자인 패턴 입문
-Headfirst Design Pattern
-나무위키, 위키백과, 네이버백과
-리팩토링구루(https://refactoring.guru/ko)

반응형