티스토리 뷰

 

 

 

Singleton 디자인패턴은 객체 지향 프로그래밍에서 매우 중요한 역할을 하는 패턴 중 하나입니다.

싱글톤 패턴은 어떤 클래스가 최대 한 번의 인스턴스만을 가지고, 그 인스턴스에 대한 전역적인 접근점을 제공하며, 이 인스턴스를 성할 때의 제어를 보장합니다.

이 글에서는 Singleton 패턴의 개념, 사용법, 그리고 주의할 점에 대해 알아보겠습니다.

 

 

 

코딩고양이

 

 

 

 

 

Singleton

 

 

Singleton 개념

 

Singleton 패턴은 아래의 핵심 원칙을 따릅니다.

 

유일한 인스턴스

해당 클래스는 오직 하나의 인스턴스만을 가지게 됩니다.

 

전역적 접근

어디에서든지 이 유일한 인스턴스에 접근할 수 있는 전역적인 접근을 제공합니다.

그래서 어디서든 접근할 수 있게 static 메소드를 사용합니다.

 

비공개 생성자

어디서든지 접근은 가능하지만 외부에서 생성자를 생성할 수 없게 합니다.

간접적으로 생성하도록 메서드를 통하여 인스턴스를 생성하여 가져가게 합니다.

 

테스트 어려움

전역 상태에서 이 인스턴스를 사용하기 때문에 테스트하기 어렵습니다.

 

메모리 낭비 방지

서버를 기동하였을 때 static을 사용하여 메모리(heap)영역에 한번 생성 하고 서버가 기동하는 동안 그 메모리 영역만 차이하기 때문에

메모리 낭비를 방지 할 수 있습니다.

 

 

 

 

 

 

Singleton 패턴은 언제 많이 사용할까?

 

데이터베이스 커넥션풀, 스레드 풀, 캐시, 로그 기록 객체, 설정 정보 등

주로 공통된 객체를 여러개 생성해서 사용해야하는 상황에 많이 사용되는 것을 볼 수 있습니다.

 

 

 

 

 

 

Singleton 패턴의 구현

 

Singleton JAVA 샘플 코드를 보여드리겠습니다.

import org.springframework.stereotype.Component;

@Component
public class Singleton {

    // 단 1개만 존재해야 하는 객체의 인스턴스로 static으로 선언
    private static Singleton instance;

    // private 생성자로 외부에서의 인스턴스화 방지
    private Singleton() {}

    // 전역에서 접근 할 수 있는 public static
    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }

    public void performAction() {
        System.out.println("싱글톤 메서드 작동하고 싶은거 만들면 된다");
    }
}

 

테스트

public class Main {
    public static void main(String[] args) {
        // 싱글톤 인스턴스 획득
        Singleton singleton1 = Singleton.getInstance();
        Singleton singleton2 = Singleton.getInstance();

        // 두 인스턴스가 동일한지 확인
        System.out.println(singleton1 == singleton2);                       // 출력: true
    }
}

 

즉, 싱글톤 객체를 호출하면 동일한 인스턴스가 온다는 것을 알 수 있습니다.

 

 

 

 

 

Singleton 패턴의 사용법

 

싱글톤 패턴의 구현에서 이미 Component를 만들었다는 가정하에 코드를 작성하게 되었다.

Component를 사용하려면 Spring을 사용한 것이다.

 

1. Singleton 빈 생성하기

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig {

    @Bean
    public Singleton singleton() {
        return new Singleton();
    }
}

 

2. Singleton 빈 사용하기

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class SomeService {

    private Singleton singleton;

    @Autowired
    public SomeService(Singleton singleton) {
        this.singleton = singleton;
    }

    public void doSomething() {
        singleton.performOperation();
    }
}

 

 

 

 

 

 

 

 

Singleton 패턴의 주의할 점

 

멀티스레딩 환경

저희는 전역에서 언제든지 싱글톤 패턴의 객체의 인스턴스를 호출해서 사용할 수 있었습니다.

A라는 클라이언트가 해당 인스턴스를 사용하고 있는데 B 클라이언트가 데이터를 변경하면 A클라이언트에게도 변경된 데이터가 보이게 됩니다.

그럼 오류 화면이든 엉뚱한 데이터가 내려오게 되겠죠?

그래서 멀티스레드 환경에서는 동기화 (Synchroized) 를 해주어 스레드를 안전하게 만듭니다.

예시 코드)

public class SingletonSynchronized{
 
    private static SingletonSynchronized instance;
 
    private SingletonSynchronized(){}
     
    public static synchronized SingletonSynchronized getInstance(){
        if(instance == null){
            instance = new SingletonSynchronized();
        }
        return instance;
    }
 
}

 

또한, instance가 없을 때 서로 다른 클라이언트들이 드물지만 동시에 getInstance() 메서드를 실행하면 각각 새로운 Instance를 생성 할 수도 있습니다.

 

테스트 어려움

싱글톤 객체의 상태가 다른 테스트에 영향을 미칠 수 있기 때문에, 각 테스트 간에 상태가 예측하기 어려울 수 있습니다.

특히 테스트 순서에 따라 결과가 달라질 수 도 있습니다.

만약에 Singleton 객체의 구현이 변경이 되면 다른 코드에 영향이 미칠 수 있으므로 테스트가 어려워 집니다.

Singleton 패턴은 의존성 관리가 어렵기 때문에 른 대안으로 Dependency Injection 이라고 하는 의존성 주입을 고려하는 것이 좋습니다.

 

 

 

 

 

활용하기

 

예시 : 환경설정 관리

애플리케이션 전체에서 하나의 환경 설정을 유지하고 관리할 때 싱글톤 패턴을 사용한 예시

public class ConfigurationManager {
    private static ConfigurationManager instance;
    private Properties properties;

    private ConfigurationManager() {
        // Load configuration properties.
        properties = new Properties();
        // Load properties from a file or other source.
    }

    public static ConfigurationManager getInstance() {
        if (instance == null) {
            instance = new ConfigurationManager();
        }
        return instance;
    }

    public String getProperty(String key) {
        return properties.getProperty(key);
    }
}

Singleton 패턴은 많은 디자인 패턴 중의 하나로, 적절한 상황에서 활용함으로써 프로그램의 구조를 더 효율적으로 만들 수 있습니다. 따라서 프로그래머들은 Singleton 패턴의 특징과 원칙을 잘 숙지하고 적재적소에 활용하는 것이 중요합니다.

 

 

 

감사합니다.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
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
29 30 31
글 보관함