본문 바로가기
Back-end/Java

[JAVA] 불필요한 객채 생성을 막자. 싱글톤 패턴과 정적 초기화 블럭

by whatamigonnabe 2022. 7. 9.

동일한 기능을 하는 객체는 계속 만들어 쓰기 보단 하나만 만들어서 재사용하는 것이 좋다.

필요 상황

자바 언어 학습을 위해 텍스트 기반 게임을 만드는 중, 아래처럼 '스킬'이라는 클래스를 생성해서 사용했다. 그런데 정확히 동일한 스킬들이 매번 반복 사용되는 문제가 있을 것 같아, 해결방법을 모색해보았다.

public class Skill {
    private String skillName;
    private int addAttackPower;
    .
    .
    .
}
// 유닛 객체
public class Unit {
    private String unitName;
    private ArrayList<Skill> skillSet; // 여러 유닛 인스턴스가 동일한 기능의 여러 스킬 인스턴스를 가짐.
    .
    .
    .
}

 

해결방법

1. 싱글톤 패턴

첫번째로 찾은 방법은 싱글톤 패턴을 이용하는 것이다.

더보기

싱글톤 패턴은 1)생성자를 private으로 구현하여 외부에서 추가적인 인스턴스 생성을 막고 2) static 변수에 해당 인스턴스를 하나 만들어 저장하고 3)static 메서드로 2)번의 하나의 객체를 반환하여 '유일한 객체를 만들어 관리하는 것'이다.

 

그러나 나의 경우는 스킬이라는 클래스에 여러 기능의 인스턴스가 있는 경우이지만, 같은 기술의 유일성을 보장하고 싶었다. 그래서 아래와 같이 스태틱 배열을 만들었다.

public class Skill {
    //1. private으로 하나의 객체만 담은 변수 설정
    private static List<Skill> skillSet = null;

    //2. private 생성자로 추가 객체생성 차단
    private Skill() {
    }

    //3. public static으로 객체 호출 메서드 생성
    public static List<Skill> getInstance() {
        if(skillSet == null) {
            skillSet.add(fly());
            ...
            skillSet.add(fire());
            return skillSet;
        }
        return skillSet;
    }

    //4. 각 스킬 인스턴스 생성 메서드(private으로 따로 호출될 일 없음)
    private Skill fly() {
    ...
    return fly;
}

    private Skill fire() {
        ...
        return fire;
    }
}

위와 같이 하면, 앞으로 Skill.getInstance()를 통해 하나뿐인 스킬들에 접근하여 사용할 수 있다.

 

2. 정적 초기화 블럭

다른 방법으로는 정적 초기화 블럭을 사용할 수도 있다.

더보기

정적 초기화 블럭이란, 간단히 말하면  클래스 내부에서 인스턴스 생성 전에 먼저 실행되는 블럭이다. 따라서 이 블럭 안에서 인스턴스를 미리 생성해서 스태틱 변수에 할당한 후, 메서드를 통해 같은 객체를 참조하게 하면 된다.

 

public class Skill {
    //정적 변수 선언
    private static List<Skill> skillSet = null;

    //정적 초기화 블럭
    static {
        skillSet.add(new Skill( ...);
        ...
        skillSet.add(new Skill( ...);
    }

    //스태틱 호출 메서드
    public static List<Skill> getInstance() {
    	return skillSet;
    }
}