[英]Factory pattern with interface, how to avoid cast
我嘗試使用接口實現工廠模式以創建不同類型的響應,但我不知道我是否做得對。 當我用工廠類調用我的方法SetExceptionResponse
時,我必須SetExceptionResponse
轉換它。
界面 :
public interface IResponse
{
int ErrorCode { get; set; }
HeaderResponse HeaderResponse { get; set; }
IResponse SetExceptionResponse(int code, string title, string[] errors);
}
主要班級:
public class Response : IResponse
{
public int ErrorCode { get ; set ; }
public HeaderResponse HeaderResponse { get; set; } = null;
public virtual IResponse SetExceptionResponse(int code, string title, string[] errors)
{
HeaderResponse headerResponse = new HeaderResponse();
if (errors.Length > 0)
{
foreach (string item in errors)
headerResponse.ErrorList.Add(item);
}
headerResponse.Title = title;
headerResponse.StatusCode = code;
return new Response
{
ErrorCode = code,
HeaderResponse = headerResponse
};
}
}
繼承主類的其他類:
public class DeleteShipmentResponse : Response
{
public string Value { get; set; }
public override string ToString()
{
return JsonConvert.SerializeObject(this);
}
public override IResponse SetExceptionResponse(int code, string title, string[] errors)
{
HeaderResponse headerResponse = new HeaderResponse();
if (errors.Length > 0)
{
foreach (string item in errors)
headerResponse.ErrorList.Add(item);
}
headerResponse.Title = title;
headerResponse.StatusCode = code;
return new DeleteShipmentResponse
{
ErrorCode = code,
HeaderResponse = headerResponse
};
}
我的工廠類:
public static class ResponseFactory
{
public static IResponse CreateResponse()
{
return new Response();
}
public static IResponse CreateDeleteResponse()
{
return new DeleteShipmentResponse();
}
public static IResponse CreateShipmentResponse()
{
return new ShipmentResponse();
}
public static T CreateResponse<T>()
where T : IResponse
{
return (T)CreateResponse(typeof(T));
}
public static IResponse CreateResponse(Type type)
{
if (type == typeof(Response))
return CreateResponse();
if (type == typeof(DeleteShipmentResponse))
return CreateDeleteResponse();
else if (type == typeof(ShipmentResponse))
return CreateShipmentResponse();
else
throw new ArgumentOutOfRangeException(string.Format(CultureInfo.InvariantCulture, "Unrecognized type [{0}]", type.FullName), "type");
}
}
因此,當我使用工廠創建 DeleteShipmentResponse 並調用 SetExeceptionResponse 時,我會這樣做:
DeleteShipmentResponse result = (DeleteShipmentResponse)ResponseFactory.CreateResponse<DeleteShipmentResponse>().SetExceptionResponse(500, "Exception in DeleteShipment()", new string[] { ex.Message });
我必須使用 DeleteShipmentResponse 進行轉換,否則會拋出異常。
如何在不對 DeleteShipmentResponse 進行類型轉換的情況下獲得此信息? 我必須使用通用接口嗎?
感謝幫助
如果所有IResponse
都可以使用無參數構造函數,則可以使IResponse
“自身的”泛型,即T
約束為IResponse<T>
:
public interface IResponse<T> where T : IResponse<T>
{
int ErrorCode { get; set; }
HeaderResponse HeaderResponse { get; set; }
T SetExceptionResponse(int code, string title, string[] errors);
}
public class Response<T> : IResponse<T> where T : IResponse<T>, new
{
public int ErrorCode { get; set; }
public HeaderResponse HeaderResponse { get; set; } = null;
public virtual T SetExceptionResponse(int code, string title, string[] errors)
{
HeaderResponse headerResponse = new HeaderResponse();
.....
return new T
{
ErrorCode = code,
HeaderResponse = headerResponse
};
}
}
public class DeleteShipmentResponse : Response<DeleteShipmentResponse>
{
...
public override DeleteShipmentResponse SetExceptionResponse(int code, string title, string[] errors)
{
....
return new DeleteShipmentResponse
{
ErrorCode = code,
HeaderResponse = headerResponse
};
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.