결국 인터페이스를 만들수 없었다는 슬픈 이야기
따로 블로그도 안하니 여기다가 붙여본다
using System;
using System.Reflection;
using UnityEngine;
/*
//사용 방법
public class TestClass
{
// Factory를 이용하려면 생성자는 nonpublic이어야 한다.
TestClass() { }
bool Initialize(int a, float b, string c)
{
// false를 리턴하면 실패하고 null 이 결과값으로 전달된다
return true;
}
}
//생성
TestClass t = Factory.Create<TestClass>(0, 1.2f, "");
*/
/// <summary>
/// 매개변수의 유효성을 검사하고 유효하지 않으면 인스턴스를 생성시키지 않기 위해서 정적 팩토리 메소드를 사용한다.
/// 리플렉션을 사용하여 매 프레임마다 쓰면 느리기에 로딩 및 초기화시에만 사용합시다.
/// 생성자를 private로 선언해야 합니다
/// </summary>
public static class Factory
{
public static T Create<T>(params object[] args) where T : class
{
T instance = null;
try
{
instance = (T)Activator.CreateInstance(typeof(T), BindingFlags.Instance | BindingFlags.NonPublic, null, null, null);
// 매개변수 타입 배열 생성
Type[] argTypes = Array.ConvertAll(args, arg => arg.GetType());
// Initialize 메소드 호출
MethodInfo initializeMethod = typeof(T).GetMethod("Initialize", BindingFlags.Instance | BindingFlags.NonPublic, null, argTypes, null);
if (initializeMethod == null)
{
Debug.Assert(false, $"Initialize 메소드를 찾을 수 없습니다: {typeof(T)}");
return null;
}
if ((bool)initializeMethod.Invoke(instance, args) == false)
{
Debug.Assert(false, $"Factory::Create<{typeof(T)}> 생성실패!!");
return null;
}
}
catch (MissingMethodException)
{
Debug.Assert(false, $"{typeof(T)}의 생성자를 private로 선언해야 합니다.");
}
catch (Exception ex)
{
Debug.LogException(ex);
}
return instance; // 객체 생성 성공
}
}
using FluffyDuck.Util;
using System.Reflection;
using System.Threading.Tasks;
using System;
using UnityEngine;
/*
// 사용 방법
public class TestClass : MonoBehaviour
{
bool Initialize(int a, float b, string c)
{
// false를 리턴하면 실패하고 null 이 결과값으로 전달된다
return true;
}
}
// 생성
MBFactory.Create<TestClass>("Assets/프리팹키", Transform, (TestClass t) => { }, 0, 1.2f, "");
*/
/// <summary>
/// FactoryCore의 MonoBehaviour 버전
/// </summary>
public abstract class MBFactory
{
static T CreateInstance<T>(GameObject obj, params object[] args) where T : MonoBehaviour
{
T instance = obj.GetComponent<T>();
// 매개변수 타입 배열 생성
Type[] argTypes = Array.ConvertAll(args, arg => arg.GetType());
// Initialize 메소드 호출
MethodInfo initializeMethod = typeof(T).GetMethod("Initialize", BindingFlags.Instance | BindingFlags.NonPublic, null, argTypes, null);
if (initializeMethod == null)
{
Debug.Assert(false, $"Initialize 메소드를 찾을 수 없습니다: {typeof(T)}");
return null;
}
try
{
if ((bool)initializeMethod.Invoke(instance, args) == false)
{
Debug.Assert(false, $"MBFactoryCore::Create<{typeof(T)}> 생성 실패!!");
GameObject.Destroy(obj);
return null;
}
}
catch (TargetException e)
{
Debug.Assert(false, $"생성한 프리팹에 {typeof(T)} 컴포넌트가 붙어 있는지 확인해보세요.");
Debug.LogException(e);
}
catch (Exception e) { Debug.LogException(e); }
return instance;
}
public static void Create<T>(string path, Transform parent, Action<T> cb, params object[] args) where T : MonoBehaviour
{
try
{
GameObjectPoolManager.Instance.GetGameObject(path, parent, (GameObject obj) =>
{
T instance = CreateInstance<T>(obj, args);
cb?.Invoke(instance);
});
}
catch (Exception e)
{
Debug.Assert(false, e.ToString());
}
}
public async static Task<T> CreateAsync<T>(string path, Transform parent, params object[] args) where T : MonoBehaviour
{
try
{
var obj = await GameObjectPoolManager.Instance.GetGameObjectAsync(path, parent);
return CreateInstance<T>(obj, args);
}
catch (Exception e)
{
Debug.Assert(false, e.ToString());
return null;
}
}
}
생각해보니 MB팩토리는 오브젝트풀을 사용하기때문에 단독으로는 못쓰겠구나. 하지만 그 또한 운명인것을...
장점이뭔데
써 있잖아
new는 무조건 만들어지는데 얘는 조건이 안되면 바로 인스턴스 자살행임
그럼안좋은거아니냐
사람을 만들려고 했는데 좀비가 나오면 곤란할때가 있잖아
인스턴스의 초기화 과정이 많아지면 많아질수록 데이터에서 체크해야 할것도 많고 사람이 실수하는 경우도 있고.. 인생은 알 수 없지
너 천재냐?