싱글톤 패턴

MIN.DI·2021년 4월 27일
0

TIL

목록 보기
5/15

싱글톤패턴(singleton pattern) 은 객체 지향 프로그램에서 인스턴스를 단 하나만 생성하는 디자인 패키지이다.
예를 들어 어떤 회사의 직원들을 객체 지향 프로그램으로 구현할 때, 직원은 여러 명이지만 회사는 하나이다.
이런 경우 직원 인스턴스는 여러개를 생성하지만, 회사 객체는 하나만 생성한다.


문제

자동차공장은 유일한 객체이고, 이 공장에서 생산되는 자동차는 제작될때마다 고유번호가 부여된다.
자동차 번호가 10001부터 시작되어 자동차가 생성될때마다 10002, 10003 이렇게 번호가 붙도록 자동차 공장 클래스, 자동차 클래스 생성.
두 클래스는 CarFactoryTest테스트코드가 수행될 수 있도록 구현

CarFactoryTest 테스트코드

CarFactory factory = CarFactory.getInstance();	//싱글톤 패턴
	Car mySonata = factory.createCar();	//메서드에서 Car생성
	Car yourSonata = factory.createCar();
		
System.out.println(mySonata.getCarNum());	//10001출력
System.out.println(yourSonata.getCarNum());	//10002출력

출처 : Do it자바 프로그래밍 입문 (p.196)


풀이

문제와 CarFactoryTest 의 테스트코드를 분석해보면,
CarFactory 클래스에는 싱글톤 패턴 구현에 이용되는 getInstance() 메서드와
자동차를 생성하는 createCar()메서드가 필요하다.

그리고 Car클래스에는 자동차에 고유 번호를 부여하는 메서드와,
이 번호를 반환하는 getCarNum()메서드가 필요하다.


먼저 CarFactory 클래스를 구현해보자.

싱글톤 패턴으로 프로그램을 구현하는 방법은 다음과 같다.

//static으로 유일한 인스턴스 생성하기
private static 클래스명 instance = new 클래스명();	

//private생성자 만들기
private 클래스명() {}	

//인스턴스를 외부에서 참조할 수 있도록 get메서드 구현
public static 클래스명 getInstance() {	
	if(instance == null){
    	  instance = new 클래스명();
    	}
    	return instance	//유일하게 생성된 인스턴스 반환

CarFactory 클래스를 싱글톤 패턴으로 구현해보면

static private CarFactory instance = new CarFactory ();

private CarFactory () {}
	
public static CarFactory getInstance() {
	if (instance == null)
		instance = new CarFactory();
	return instance;
	}
public Car createCar() {
	Car car = new Car();	
	return car;
}

위와 같이 구현할 수 있는데,
이 때 createCar() 메서드는 Car클래스를 참조하므로 오류가 발생한다.
따라서 CarFactory클래스보다 Car클래스를 먼저 생성하는 것이 좋다.

여기에서 createCar() 메서드가 없다면 문제의 테스트코드에서 새로운 자동차를 생성할 때

Car mySonata = new Car();
Car yourSonata = new Car();

와 같은 형태로 생성했을 것이다.

다음은 Car클래스 코드이다.

static private int serialNum = 1000;
int carNum;

public Car(){
	serialNum++;	//자동차(인스턴스)가 생성딜때마다 serialNum이 1001번부터 자동 채번됨.
    carNum = serialNum;	//증가된 값을 인스턴스 변수에 부여
}

public int getCarNum(){
	return carNum;
}

이 문제처럼 새로운 인스턴스가 생성될때마다 어떤 규칙에 따라 새로운 고유 값을 부여해야 할 때는
static변수로 고유값을 선언하고, 생성자에서 해당 변수에 규칙을 설정하면 된다.

serialNum을 바로 자동차 번호로 사용하지 않고 carNum이라는 인스턴스 변수를 따로 생성한 이유는, 일반적으로 어떤 객체에 부여하는 고유번호는 숫자(int)로만 이루어져있지 않기 때문이다.
대부분의 경우 고유번호는 문자(string)와 숫자가 결합된 형태이며, serialNum은 단순 채번만 해주는 역할이기 때문에
고유 번호를 출력하는 String 타입의 변수를 따로 선언하는것이 일반적이다.
해당 문제에서는 굳이 car Num 변수를 사용하지 않아도 되지만, 일반적인 경우를 따랐다.

profile
내가 보려고 쓰는 블로그

0개의 댓글