Quick Flow
factory는 Instantiate를 감추는 wrapper가 아니라, “이 spawn request는 어떤 prefab·config·parent·lifetime으로 생성되고 언제 사용 가능해지는가”를 한 곳에서 결정하는 경계입니다. 호출부는 request와 ready 결과만 다루고, pool return·Addressables release 같은 ownership을 임의로 섞지 않습니다.
public interface IEnemyFactory
{
Enemy Spawn(EnemyDefinition definition, SpawnRequest request);
}
public sealed class EnemyFactory : IEnemyFactory
{
public Enemy Spawn(EnemyDefinition definition, SpawnRequest request)
{
Enemy enemy = Object.Instantiate(definition.Prefab, request.Position, request.Rotation, request.Parent);
enemy.Initialize(definition, request.Team);
return enemy;
}
}| 생성 요구 | factory가 정할 것 | 호출부가 확인할 것 |
|---|---|---|
| 같은 prefab의 즉시 spawn | prefab·parent·initial state | 반환 object가 ready인지 |
| 반복되는 projectile·effect | pool get/release owner | return 시 reset·unsubscribe |
| remote/local asset load | Addressables handle·cancel·release | await 뒤 object가 아직 필요한지 |
| 여러 enemy definition | key·ScriptableObject config·validation | unknown key·fallback 정책 |
생성 정책을 호출부에서 빼기
호출부마다 Instantiate, team, stat, target, parent, event subscribe를 반복하면 새 field가 생길 때 초기화 누락이 생깁니다. factory는 definition 선택, prefab 또는 pool 선택, required initialization, failure handling을 모읍니다. 생성 뒤 gameplay state를 계속 바꾸는 책임까지 factory에 몰아넣기보다, spawn 시 반드시 유효해야 하는 invariant만 초기화합니다.
direct prefab reference가 한 위치에 있고 definition도 하나라면 factory는 과할 수 있습니다. type·difficulty·biome·network role에 따라 생성 규칙이 달라지거나, 여러 호출부가 같은 initialization을 반복할 때 도입합니다. enum switch를 다른 class로 숨기는 것이 목적이 아니라 policy 변경을 한 위치에서 test하는 것이 목적입니다.
pool·Addressables와 수명
ObjectPool<T>는 get, release, destroy callback과 maximum size 같은 재사용 정책을 제공하지만, 반환될 object가 listener·coroutine·particle·child state를 초기화하는지는 factory 또는 pooled type의 계약입니다. double release나 scene unload 뒤 release를 누가 막는지도 owner를 정합니다.
Addressables는 local 또는 remote asset과 dependency를 asynchronous하게 load합니다. factory가 Addressables를 쓴다면 “spawn request가 취소됐을 때 handle을 누가 release하는가”, “load 완료 뒤 scene이 unload됐으면 무엇을 하는가”, “instance release와 asset handle release를 어느 owner가 하는가”를 type과 API에 맞게 설계합니다. 동기 Spawn interface인 척하면서 내부 loading을 fire-and-forget으로 두면 호출부가 ready 이전 object를 사용하게 됩니다.
생성 경계 검증
factory test는 반환 type만 확인하지 않습니다. unknown definition, missing prefab, duplicate spawn, cancellation, pool reuse, scene unload에서 초기화·ready·release가 정확히 한 번 일어나는지 확인합니다. factory가 고른 config와 runtime instance state도 분리해 shared ScriptableObject asset이 actor별 state로 변하지 않게 합니다.
factory 이름만 두고 호출부가 생성 뒤 team·stats·parent·event를 다시 설정하면 생성 경계는 그대로 흩어집니다. 반대로 asynchronous load와 pool return을 factory 안에서 숨길 때는 ready·cancel·release owner를 public contract에 드러내세요.
참고 링크
2 sources