728x90
프로젝트를 진행하면서 아래 예제 코드와 같이 형타입에 따라 다른 객체를 생성해야 하는 경우가 있습니다.
if( data is DataTypeA a)
{
var model = new DataModelA(a);
list.Add(model);
}
else if( data is DataTypeB b)
{
var model = new DataModelB(b);
list.Add(model);
}
// 엄청 긴 if 문~
위 예제 코드와 같은 구조로 개발을 하게 되면 데이터 타입이 추가될 때마다, if 문은 계속 길어질 수 밖에 없고 데이터 타입에 따라 DataModel을 생성하는 논리가 달라지면서 if문 내부도 복잡해져갔습니다. 이러한 구조로 인해 점점 코드는 더러워집니다. 이를 해결하기 위해 아래와 같이 리플렉션을 활용해서 DataModel을 생성하는 논리를 분리했습니다.
// DataType에 따라 DataModel을 생성해주는 Factory 클래스
static class DataFactory
{
// DataModel 을 생성하는 함수를 캐싱하기 위한 속성이다.
private static IDictionary<MethodInfo, ParameterInfo> _createDataMethods;
private static IDictionary<MethodInfo, ParameterInfo> CreateDataMethods
{
get
{
// Singleton 패턴을 활용한다.
if(_createDataMethods is null)
{
_createDataMethods = new Dictionary<MethodInfo, ParameterInfo>();
// DataFactory 클래스에서 static 이면서 private 또는 protected 인 함수의 methodInfo를 수집한다.
var methodInfos = typeof(DataFactory).GetMethods(BindingFlags.Static | BindingFlags.NonPublic);
foreach (var methodInfo in methodInfos)
{
// 수집한 methodInfo 중에 반환 타입이 DataType인 함수만 수집한다.
if (methodInfo.ReturnType == typeof(DataModel))
{
var parametersInfos = methodInfo.GetParameters();
// 수집한 함수의 변수가 1개이면서 DataType을 상속할 수 있는 타입인 함수만 수집한다.
if(parametersInfos.Length == 1
&& typeof(DataType).IsAssignableFrom(parametersInfos[0].ParameterType)
{
_createModelMethods.Add(methodInfo, parametersInfos[0]);
}
}
}
}
return _createDataMethods;
}
}
public static DataModel CreateDataModel(DataType dataType)
{
foreach(var pair in CreateDataMethods)
{
// dataType 를 DataModel로 변환하는 함수인지 확인한다.
if(pair.Value.ParameterType == dataType.GetType())
{
return (DataModel)pair.Key.Invoke(null, new object[] { dataType });
}
}
throw new InvalidCastException($"{dataType.GetType()}을 Model로 변환하는 함수가 없습니다.");
}
#region 변환 함수 목록
private static DataModel CreateDataModel(DataTypeA dataType)
{
return new DataModelA(a);
}
private static DataModel CreateDataModel(DataTypeB dataType)
{
return new DataModelA(b);
}
#endregion
}
이제 if 문 대신 아래와 같이 쓰면 됩니다.
list.Add(DataFactory.CreateDataModel(data));
[출처]
728x90
'C#' 카테고리의 다른 글
힙, 스택 그리고 GC (0) | 2023.12.20 |
---|---|
Virtual, Abstract, Interface (0) | 2023.11.06 |
IPC(Inter-Process Commnication) (0) | 2023.11.04 |
윈도우 메세지 종류들 List Of Windows Messages | WndProc (0) | 2023.11.04 |
GDI 개체 관리 (0) | 2023.11.04 |