簡體   English   中英

帶接口的工廠模式,如何避免強制轉換

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM