오늘은 코드를 짜는 도중에 생성자와 관련되어서 한 번 에러가 났다.
A라는 클래스의 생성자에서 B 클래스를 만들고, B클래스는 A클래스를 참조하는 경우였다.
이런 구조로 코드가 짜여있어서 생성자가 끝나지 않고 계속해서 순환해서 돌다가 스택이 넘쳐버리는 사태가 발생했다.
해당 구조를 적당히 재현해보면 다음과 같이 된다.
class DataManager
{
public DataManager()
{
LoadMonsters();
}
public void LoadMonsters()
{
new Monster(어쩌구 저쩌구);
}
}
class Monster
{
public Monster()
{
SetDropTable()
}
public void SetDropTable()
{
DataManager.Instance.LoadTable(어쩌구 저쩌구)
}
}
DataManager라는 클래스의 생성자에서 Monster를 만들었고 Monster는 필요한 정보를 세팅하기 위해 또 생성자에서 DataManager를 참조하게 되는 구조라서 계속 생성자가 반복되다가 결국엔 스택 오버플로우가 나게된다.
해당 클래스가 만들어지면 자동으로 필요한 정보들이 생성되고 필요한 객체들이 만들어지길 바래서 짠 구조였지만 그렇게 마음대로 되지 않았다.
이 문제를 해결하기 위해 간단하게 LoadMonsters() 에 해당하는 메소드를 외부에서 호출하도록 바꿨지만 다른 방법이 없을지 조언을 구했다.
여러 가지 방법이 있겠지만 위에서 내가 쓴 바와 같이 Init()메소드와 같이 초기화용 메소드를 하나 만들고 해당 객체를 관리하는 객체에서 생성 직후 Init을 호출해주는 방법이 있다.
또 하나의 방법은 프로퍼티를 활용해서 내부에 인스턴스를 보관하는 static 변수를 하나 두고 Get을 통해 접근할 때 필요한 초기화까지 같이 진행하는 것이다.
조금은 다른 개념인데 DI라는 개념도 있다.
의존성 주입이라는 것으로 객체가 다른 객체에 따라 영향을 받는 것을 의존성이 있다고 하는데 이 의존성을 가진 것을 외부에서 전달해주는 것이다.
예를 들면 먹는다라는 eat(food) 메소드가 있을 때 food에 따라 구워 먹을지 삶아 먹을지 결정된다고 하면 eat은 food에 의존한다. 여기서 food를 eat이 결정하는게 아니라 외부에서 전달해주면 그게 바로 의존성 주입이다.
이런 개념까지 잘 활용해서 다음번에는 스택 오버플로우를 볼 일 없이 클래스 구조를 짜고 초기화를 시킬 예정이다.
'부트캠프' 카테고리의 다른 글
정렬 알고리즘 (0) | 2023.09.04 |
---|---|
팀 콘솔RPG 프로젝트 마무리 (0) | 2023.09.01 |
팀 콘솔 RPG2 (스킬 구현) (0) | 2023.08.29 |
팀 콘솔RPG 프로젝트 (0) | 2023.08.28 |
콜백함수를 왜 쓰는가? (0) | 2023.08.25 |