자바, 싱글톤 패턴 실습

2022. 9. 3. 11:16자바

728x90
반응형

싱글톤 패턴은 디자인 패턴 중 하나로, 인스턴스가 하나만 존재해야하는 경우에 대한 클래스 템플릿을 의미한다. 현재 자바를 두권의 책(가장 빨리 만나는 코어 자바9, Do it! 자바 프로그래밍 입문)으로 학습 중이다. 이 중 Do it! 자바 프로그래밍 입문에서 나온 예제를 가지고 싱글톤 패턴 실습을 진행하고자 한다.


회사 클래스

어떤 회사의 직원들을 객체 지향 프로그램으로 구현한다고 가정할 때 직원은 여러명이겠지만 회사는 하나이다. 이러한 경우에 회사는 싱글톤 패턴으로 구현할 수 있다.

 

이때 싱글톤 패턴은 생성자와 인스턴스를 private으로 구현하고, public 메서드를 통해 외부에 인스턴스를 반환하는 형식으로 구현된다.

 

// Company.java
package singleton;

public class Company {
    private static Company instance = new Company(); // 유일하게 생성되는 정적 인스턴스
    private Company() {} // 기본생성자 private으로 호출

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

- 생성자와 인스턴스를 private으로 만들었다. 특히 instance는 하나만 존재해야하기에 이는 static으로 구현해 유일하게 생성되도록 구현했다. 외부에서는 getInstance() 메서드를 호출해 인스턴스를 외부에서 참조할 수 있도록 했다. instance의 경우 클래스 인스턴스이기에 초기화가 되지 않는 경우에는 null의 값을 가진다. 따라서 인스턴스가 없다면 새로운 인스턴스를 만들고, 그게 아니라면 기존의 instance를 반환하여 인스턴스가 유일하도록 만든다.

 

// CompanyTest.java
package singleton;

public class CompanyTest {
    public static void main(String[] args){
        Company myCompany1 = Company.getInstance();
        Company myCompany2 = Company.getInstance();
        System.out.println(myCompany1 == myCompany2)
    }
}

- true가 반환된다.

 

 

 

싱글톤 패턴으로 클래스 구현 연습

자동차 공장 구현하기

 

자동차 공장은 유일한 객체이고, 이 공장에서 생산되는 자동차는 제작될 때마다 고유한 번호가 부여된다. 자동차 번호가 10001부터 시작되어 자동차가 생성될 때마다 10002, 10003 이렇게 번호가 하나씩 증가하도록 자동차 클래스를 만들자. 아래 Test 클래스를 보고 어떻게 출력이 되어야할지 확인해보자.

package CarFactory;

//예제에서는 조합을 사용해 클래스를 구현했지만 차와 차공장 사이의 의존성이 있다고 판단해 이를 내부 클래스로 구현함
import CarFactory.CarFactory.Car; 

public class CarFactoryTest {

	public static void main(String[] args) {
		CarFactory factory = CarFactory.getInstance(); // 싱글톤 패턴
		Car mySonata = factory.createCar();
		Car yourSonata = factory.createCar();
		System.out.println(mySonata.getCarNum()); // 10001 출력
		System.out.println(yourSonata.getCarNum()); // 10002 출력
	}
}

 

CarFactory 및 Car 구현

package CarFactory;

public class CarFactory {
	private static CarFactory instance = new CarFactory();
	private static int CarNum = 10000; // 차량 번호 저장
	private CarFactory() {}
	
	public static CarFactory getInstance() {
		if (instance == null) instance = new CarFactory();
		return instance;
	}
	
	public Car createCar() {
		Car newCar = new Car();
		return newCar;
	}
	
	public class Car {
		private int carNum;
		
		public Car() {
			carNum = ++CarFactory.CarNum;
		}
		
		public int getCarNum() {
			return carNum;
		}
	}
}

- 문제의 요구사항은 Car 클래스와 CarFactory 클래스를 구현하는 것이다. 단순히 클래스를 각각 따로 구현할 수 있지만 오늘 복습 차원으로 '가장 빨리 만나는 코어 자바9' 책에서 정리한 내용인 내부 클래스를 통해 구현했다. 

 

- 단순히 조합의 관계라기보단 CarFactory를 통해 Car를 만드는 것이기에 이러한 연관성을 고려해 내부 클래스로 Car 클래스를 구현했다.

 

위의 실습과 다른 부분은 정적 변수로 선언된 CarFactory의 CarNum의 값을 점차 증가시켜가며 Car의 생성자를 호출할 때마다 CarFactory의 CarNum을 점차 더하는 것에 있다. 이 점만 고려하면 쉽게 구현할 수 있다.

728x90
반응형