Manager를 설계하는 방법에 대해 생각해보고자 한다.
회사마다 사람마다 설계하는 방식이 모두 다르지만 의도는 거의 동일하기 때문에 어떻게 설계를 하든 상관은 없다만 요즘 설계 방식도 재밌어 보여서 남겨본다.
public class Singleton<T> : MonoBehaviour where T : MonoBehaviour
{
private static T instance;
public static T Instance { get { SingletonInit(); return instance; } }
private static void SingletonInit()
{
if (instance == null)
{
instance = new GameObject(typeof(T).Name).AddComponent<T>();
if (Application.isPlaying)
DontDestroyOnLoad(instance.gameObject);
}
}
}
public class GameManager : Singleton<GameManager>
{
// ...
}
public class GameManager : MonoBehaviour, IGameManager
{
[SerializeField]
private CharacterManager _characterManager;
// ..
}
// GameManager의 하위 관리자는 GameManager로의 역참조를 갖도록 한다.
public class CharacterManager : MonoBehaviour
{
private IGameManager _gameManager;
private List<BaseCharacter> _guardians = new List<BaseCharacter>();
public IGameManager GameManager
{
get { return _gameManager; }
}
public void Init(IGameManager gameManager)
{
_gameManager = gameManager;
}
// ..
}
// CharacterManager의 하위 객체는 CharacterManager로의 역참조를 갖는다.
// 이렇게 되면 모든 객체는 다른 모든 객체를 참조해올 수 있다.
public class BaseCharacter : MonoBehaviour
{
protected CharacterManager _manager;
public void Init(CharacterManager manager)
{
_manager = manager;
}
}
public interface IManager
{
void Init();
void Clear();
}
public class Managers : MonoBehaviour
{
private static Managers instance;
public static Managers Instance
{
get
{
Initialize();
return instance;
}
}
private static void Initialize()
{
if (instance == null)
{
instance = new GameObject($"@Managers").AddComponent<Managers>();
DontDestroyOnLoad(instance.gameObject);
}
}
private DBManager _db = new DBManager();
public static DBManager DB
{
get { return Instance?._db; }
}
}
public class DBManager : IManager
{
public void Init()
{
}
public void Clear()
{
}
// ...
}
일단 3가지 정도 예시를 들었지만, 결국에는 본인이 편한쪽으로 설계하는 것이 맞는 것 같다. 하지만 결국에는 회사에서 일을 하게 되면 회사에 맞게 하는 편이 좋겠지..