본문 바로가기
소프트웨어 공학

[디자인패턴] 중복을 허용하지 않는 객체 생성 - 싱글톤

by 티옌.liy 2022. 11. 15.

 

객체지향에서는 데이터 관리를

클래스로 하는 경우가 빈번한데

 

클래스로 생성한 인스턴스 객체가

중복으로 존재하면 안되고

 

단 1개만 생성되어야 하는 경우에

사용하는 디자인 패턴이다.

 

고전적인 방법이지만

어느 언어든간에 자주 사용하므로

한번 익혀두면 요긴하게 사용한다.


1. 싱글톤?

오직 하나의 객체만 생성할 수 있는 클래스를 구현하기에 Static 변수, 메서드를 활용하여 구현한다.

그러면 1번만 생성하고 Data 메모리 영역 중 static 공간에 적재되는 특징을 가지게 된다.

 

Static의 특성은 아래 글을 참고하자

 

[Java] 정적 맴버 선언 - Static 키워드

평소에 모두가 알아야 할 정보를 사람들에게 일일히 말하기 힘드니 공통으로 볼 수 있는 공지사항에 기재하는 것처럼 공통으로 사용할 값과 기능은 static으로 선언하고 어떤 객체든간에 접근 및

tyen.tistory.com

 

2. 싱글톤 사용하는 이유

가장 큰 이유는 객체를 공유하면서 생기는 보안 이슈때문인데

해당 클래스의 인스턴스가 단 1개만 존재함을 보증하는것을 주 목적으로 사용한다.

 

만약 관리자 계정 객체가 복사되서 중복으로 존재하면 무슨일이 벌어지겠는가?

그래서 객체가 중복 생성되면 안되는 경우에 사용한다.


개인 환경설정, 로그인 세션 등, 특정 용도로 중복 생성이 불가능한 고유 객체로 구성해서 보안을 유지하고

필요할 때, 공유된 고유 변수로 여러 객체에서 접근하여 편의성도 챙길 수 있는 패턴이다.

이는 메모리 최적화, 데이터 공유 편의성, 중복 생성 방지. 3가지 이점이 있다.

그러나, 얻는게 있으면 잃는것도 있는법. 대신에 코드 확장성이 크게 감소된다.

 

 

3. 싱글톤 패턴 만들기

싱글톤 패턴을 가진 클래스를 구현하는 방법은 아래와 같다.

 

1. 클래스 내부에 private 생성자 만들기

생성자를 코딩하지 않으면 컴파일러에 의해 default 생성자가 자동으로 만들어지므로 빈 생성자를 명시하여 생성한다.

또한 외부에서 생성자로 클래스를 중복 사용하지 못하도록 private으로 생성해야한다.

 

예시 코드 - private 생성자 생성
public class Company {
	private Company() {};
}

 

2. 클래스 내부에 static 고유 맴버 변수 생성

싱글톤 클래스를 사용할 고유 맴버 변수를 생성한다.

이때, 외부에서 고유 맴버 변수 값을 변경하지 못하도록 private으로 생성해야한다.

 

예시 코드 - static 고유 맴버 변수 생성
public class Company {
	private static Company instance = new Company();
	
	private Company() {};
}

 

3. 고유 변수를 사용할 수 있도록 public get 메서드 새성

일반 메서드이면, 인스턴스화를 진행해야만 메서드를 쓸 수 있으므로

static으로 get 메서드를 선언하여 인스턴스 과정 없이 호출이 가능하도록 구성한다.

또한, 외부에서 싱글톤 클래스를 사용할 수 있도록 public으로 get 메서드를 생성한다.

 

예시 코드 -  public get 메서드 생성
public class Company {
	private static Company instance = new Company();
	
	private Company() {};
	
	public static Company getInstance() {
		if(instance == null) {
			instance = new Company();
		}
		
		return instance;
	}
}

 

 

4. 싱글톤 사용하기

싱글톤 클래스를 사용할 수 있도록 고유 맴버 변수를 객체에 할당한다.

 

예시 코드 - 싱글톤 클래스를 객체에 할당하기
public class MainClass {

	public static void main(String[] args) {
		Company company1 = Company.getInstance();
		Company company2 = Company.getInstance();
		Company company3 = Company.getInstance();
		
		System.out.println(company1);
		System.out.println(company2);
		System.out.println(company3);
	}
}
실행 결과
testpackage@1d8d30f7
testpackage@1d8d30f7
testpackage@1d8d30f7
패키지명@heap메모리 주소값

 

3가지 인스턴스 객체가 같은 heap 메모리 주소 값을 참조함을 확인할 수 있다.

즉, 3가지 인스턴스 객체가 이름만 다르지 사실 동일한 1가지 객체인것이다.

 

 

5. 싱글톤 사용 시 주의사항

싱글톤 패턴 사용시 주의해야할 항목을 기술한다.

 

1. 클래스와 인스턴스 객체간의 결합도가 높아진다.

싱글톤 인스턴스 객체가 매우 다양한 기능을 수행하거나, 공유하는 데이터가 많을 때,

한 클래스가 수행하는 책임이 너무 커지는 문제가 발생할 수 있다.

이것은 코드 분석 후 기능을 나누어 모듈화 하는 방법으로 높은 결합도 문제를 완화할 수 있다.

 

2. 테스트 진행 시, 상태 값 주의

싱글톤 클래스는 static으로 선언했기에, 프로그램이 종료될 때까지 해제되지 않는다.

때문에, 테스트 작업을 할 때 매번 상태 값을 초기화 해줘야 한다.

 

3. 멀티 스레드 사용 시, 동시성 이슈 발생 가능성

멀티 스레드 환경에서 동기화 처리를 안하고 싱글톤 클래스를 생성하면 동시성 문제로 중복 생성 될 수 있다.

때문에, 싱글톤을 사용하는 구현부에는 반드시 동기화 작업을 해줘야 한다.

 

4. 싱글톤 기반 클래스로 자식 클래스를 생성하면 안된다.

생성은 가능한데, 이러면 자식 클래스에서 싱글톤을 위한 고유 맴버 변수를 변경할 수 있어서

사실상 싱글톤 패턴이 깨지게 된다.

그래도 자식 클래스를 쓰고싶다면, 자식 클래스도 싱글톤으로 만들어야 한다.


싱글톤 동시성 해결법은 아래 블로그에 설명이 잘 되어있다.

 

디자인 패턴. 싱글턴 패턴(Singleton pattern)

정의 싱글턴(singleton)은 오직 하나의 객체만을 생성할 수 있는 클래스를 말합니다. 따라서 싱글턴 패턴을 사용하면 쉽게 객체의 유일성을 보장할 수 있습니다. 또한 일반적으로 싱글턴 객체에 대

blog.hexabrain.net

 

댓글