ios dev kangwook.

06. Singleton Pattern 본문

Design Pattern

06. Singleton Pattern

kangwook 2022. 8. 21. 22:17

전역 변수를 사용하지 않고 객체를 하나만 생성하도록 하며, 생성된 객체를 어디에서든지 참조할 수 있도록 하는 패턴

Singleton Pattern

Singleton Pattern은 클래스에 인스턴스가 하나만 있는지 확인하고, 클래스에 대해 전역적으로 접근할 수 있는 지점(point)를 제공한다.

  • uniqueInstance 멤버 변수는 Singleton의 유일한 인스턴스
  • getInstance 메서드는 static이어서 Singleton.getInstance()를 사용하여 사용자의 코드 어느 곳에서나 이 메소드에 편리하게 액세스할 수 있음

Singleton 패턴을 사용하는 이유

  • 고정된 메모리 영역을 얻으면서 한 번의 객체 생성으로 인스턴스를 사용하기 때문에 메모리 낭비 방지
  • 싱글톤으로 만들어진 클래스의 인스턴스는 전역 인스턴스이기 때문에 다른 클래스의 인스턴스들이 데이터를 공유하기 쉬움
  • Database Connection Pool처럼 공통된 객체를 여러 개 생성해서 사용해야 하는 상황에서 많이 사용
    • 쓰레드풀, 캐시, 대화상자, 사용자 설정, 레지스트리, 로그 등

Singleton Pattern 예제

  • 초콜릿 공장의 보일러가 처리할 프로세스 클래스
    • 보일러에는 아직 끓지 않는 원료를 버린다거나, 가득 차 있을 때 새로운 원료를 붓는다거나, 빈 보일러에 불을 지피는 등의 실수를 하지 않음
  • 이전 코드
    • Singleton을 사용하지 않고 코드 어디서든지 객체를 생성할 수 있음AbstractFactory : PizzaIngredientFactory 클래스
public class ChocolateBoiler {
    private boolean empty;
    private boolean boiled;
         
    public ChocolateBoiler() {
        empty = true;
        boiled = false;
    }
 
    public void fill() {
        if(isEmpty()) {
            empty = false;
            boiled = false;
        }
    }
 
    public void drain() {
        if(!isEmpty() && isBoiled()) {
            empty = true;
        }
    }
 
    public void boil() {
        if(!isEmpty() && !isBoiled()) {
            boiled = true;
        }
    }
 
    public boolean isEmpty() {
        return empty;
    }
 
    public boolean isBoiled() {
        return boiled;
    }
}
  • 싱글턴 패턴을 적용시킨 코드
public class ChocolateBoiler {
    private boolean empty;
    private boolean boiled;
    private static ChocolateBoiler uniqueInstance;
 
    private ChocolateBoiler() {
        empty = true;
        boiled = true;
    }
 
    public static ChocolateBoiler getInstance() {
        if(uniqueInstance == null) {
            System.out.println("Creating unique instance of Chocolate Boiler");
            uniqueInstance = new ChcolateBoiler();
        }
        System.out.println("Returning instance of Chocolate Boiler");
        return uniqueInstance;
    }
     
    public void fill() {
        if(isEmpty()) {
            empty = false;
            boiled = false;
        }
    }
 
    public void drain() {
        if(!isEmpty() && isBoiled()) {
            empty = true;
        }
    }
 
    public void boil() {
        if(!isEmpty() && !isBoiled()) {
            boiled = true;
        }
    }
 
    public boolean isEmpty() {
        return empty;
    }
 
    public boolean isBoiled() {
        return boiled;
    }
 

결론

  • 싱글턴 패턴은 어떠한 클래스의 인스턴스를 하나만 생성해서 사용하기 위한 생성 패턴(Creational Pattern)
  • 접근을 제어할 필요가 없는 자원을 싱글턴으로 작성하는 것은 리소스 낭비
  • 장점
    • 객체를 여러 번 생성할 필요가 없고, 기존에 생성된 것을 가져다 쓰기 때문에 메모리와 성능 측면에서 효율이 좋음
    • 다른 클래스간에 데이터 공유가 쉬움
  • 단점
    • 싱글턴을 구현하는 코드가 많이 들어감
    • private 생성자를 가지고 있어 상속이 불가능
    • 클래스 내부에서 객체를 직접 생성하기 때문에 객체 지향 설계원칙인 OCP, DIP를 위배
    • 테스트하기 힘듦
    • 동기화가 어려움(쓰레드 분기처리가 안됨)

 

 


본문은 Head First Design Pattern (2004) 를 참고하여 공부하고 작성하였음


 

'Design Pattern' 카테고리의 다른 글

08. Adapter Pattern  (0) 2022.08.23
07. Command Pattern  (0) 2022.08.22
05. Abstract Factory Pattern  (0) 2022.08.20
04. Factory Method Pattern  (0) 2022.08.18
03. Decorator Pattern  (0) 2022.04.30
Comments