[Java] 디자인 패턴과 싱글톤

디자인 패턴이란?

  • 프로그램을 설계할 때 지금 당장의 문제, 미래에 발생할 수 있는 문제와 추가될 기능 등을 고려해야하는데 이를 객체간의 관계 등을 이용하여 해결할 수 있도록 고안한 하나의 '규약'입니다.
  • 즉, 개발시 문제 발생 위험도를 최대한 줄일 수 있도록 도와줍니다.
  • 이를 자연스럽게 사용할 수 있다면 개발 시간을 많이 단축하고 효율적인 코드를 다룰 수 있을거같습니다.

이러한 디자인 패턴은 다양하게 존재하는데 이번 게시물에선 "싱글톤 패턴" 에 대하여 다루어 보겠습니다


싱글톤 패턴이란?

  • 하나의 클래스에 오직 하나의 인스턴스만 가지는 패턴으로 보통 DB연결 모듈에 많이 사용된다고 합니다.
  • 싱글톤 패턴의 객체는 서버에 많은 요청이 올때 new 를 통해 매번 새로운 객채를 생성하고 GC에 의해 삭제되는 오버헤드를 줄일 수 있습니다.
    • 장점
      1. 인스턴스 생성 비용이 줄어들 수 있습니다.
    • 단점 
      1. 생성된 하나의 인스턴스에대한 의존성이 높습니다. ( 커플링 )
        • DI를 통해 결합을 느슨하게 할 수 있습니다.
      2. TDD시 단위 테스트를 진행하기 힘들 수 있습니다.
        • 사실상 전역에서 관리되는 하나의 갹체이므로 "독립적인" 인스턴스를 만들기 어렵습니다
      3. 멀티 스레딩 환경에서의 사용에 유의해야합니다
  • 싱글톤 구현 코드
public class Singleton {
    private Singleton() {}
    private static class singleInstanceHolder{ 
        private static final Singleton INSTANCE = new Singleton();

    }
    public static Singleton getInstance(){
            return singleInstanceHolder.INSTANCE;
    }
}

이처럼 static inner class로 Thread Safe하게 사용할 수 있고, 해당 class가 호출될때 생성되므로 Lazy Loading이라고 할 수 있습니다.

 

  • 테스트
public class ThreadSafeTest {
    public static void main(String[] args) throws Exception {
        ExecutorService executorService = Executors.newFixedThreadPool(3);
        Callable<Singleton> task = new Callable<Singleton>() {
            @Override
            public Singleton call() {
                return Singleton.getInstance();
            }
        };

        Set<Future<Singleton>> set = new HashSet<>();
        for (int i = 0; i < 100; i++) {
            Future<Singleton> future = executorService.submit(task);
            set.add(future);
        }

        Singleton firstInstance = null;
        for (Future<Singleton> future : set) {
            Singleton instance = future.get();
            if (firstInstance == null) {
                firstInstance = instance; // 첫 인스턴스를 참조로 저장
            } else if (!firstInstance.equals(instance)) {
                throw new IllegalAccessException("다른 인스턴스가 생성되었습니다.");
            }
        }
        executorService.shutdown();
        System.out.println("모두 같은 인스턴스입니다");
    }
}

 

간단하게 Java로만 싱글톤 패턴의 Thread safe함을 테스트해보았습니다.

싱글톤 객체를 static 영역에 선언하여 사용하지 않고, new 로 반환한다면 위 테스트는 IlleagalAccessException을 던질것입니다.

'Java' 카테고리의 다른 글

[JAVA] Builder 패턴을 알아보자  (0) 2024.03.24
[JAVA] 팩토리 메서드 패턴  (0) 2024.03.21
[Java] ConcurrentHashMap사용하기  (0) 2023.12.24
[Java] CompletableFuture 사용하기  (0) 2023.12.24
객체 지향 프로그래밍  (0) 2023.08.30