C#/C#프로젝트

[C#Project] Player가 Inventory를 참조할 때 발생한 순환 참조 문제 (Circular Dependency)

도도돋치 2025. 4. 19. 23:14
Contents 접기
728x90

문제 상황

C# 기반으로 간단한 RPG 게임을 개발하던 중 Player 클래스는 자신의 인벤토리를 다루기 위해 InventoryManager 인스턴스를 필드로 갖고 있었고, 반대로 InventoryManager도 Player의 상태(소지 금액, 레벨 등)를 확인해야 하는 요구사항이 생겼다.

 

이때 다음과 같은 코드 구조가 되어버렸다.

public class Player {
    public InventoryManager Inventory;

    public Player() {
        Inventory = new InventoryManager(this);
    }
}

public class InventoryManager {
    private Player _player;

    public InventoryManager(Player player) {
        _player = player;
    }
}

 

Player의 생성자에서 InventoryManager를 생성하면서 자신의 인스턴스를 넘기고 있는데, InventoryManager 내부에서는 이미 Player의 상태를 접근하려고 한다.

  • 객체가 완전히 생성되기 전에 자신을 다른 객체에게 넘기는 구조 → 순환 참조 문제가 발생
  • 초기화 순서에 따라 NullReferenceException이 발생하거나, 테스트와 유지보수성이 크게 떨어지는 구조가 된다.

 

원인 분석

  • 두 객체가 서로를 강하게 참조하고 있어 결합도가 너무 높음
  • 생성자에서 서로를 직접 넘기다 보면 초기화 순서 문제 발생
  • 클래스 간 역할이 명확히 나뉘지 않아 단방향 참조 원칙이 깨짐

 

해결 방법

구조를 개선하여 Player에서만 Inventory를 참조하도록 하였다. 그리고 GameManager에서 이를 관리하도록 하였다.

 

최종 구조는 이렇게 구성했습니다.

public class GameManager
{
    private UIManager ui;
    public InventoryManager inventory;
    public Player player;
    public ShopManager shop;

    public GameManager()
    {
        ui = new UIManager();                         // 1. UIManager 먼저 생성
        inventory = new InventoryManager(ui);         // 2. InventoryManager 생성
        player = new Player(ui, inventory);           // 3. Player에 필요한 의존성 주입
        shop = new ShopManager(ui, player, inventory);// 4. 모든 객체가 준비된 후 Shop 생성
    }
}

 

이렇게 하여 객체 간 의존성 주입이 명확하고, 어떤 객체가 먼저 준비되어야 하는지 순서도 잘 알 수 있게 되었다.

 

 

마무리

클래스 간 의존성이 많아질수록 생성 순서와 참조 구조를 신중히 설계해야 하는것 같다.
이번 경험을 통해 객체 간 관계를 설계하는 능력도 한층 성장한 느낌이 든다.

항상 시작전에 어떻게 참조할 것인지 한번더 구조를 명확히 하고 구현해야겠다고 다짐했다.

728x90