簡體   English   中英

使用泛型來封裝常見的方法工作

[英]Using Generics to encapsulate common method work

我有許多WebService方法都包含一些非常的樣板代碼,用於將實際工作包裝在try / catch / finally中,並在catch / finally中執行相同的任務。 因此,作為一種封裝所有共享catch / finally內容的方法,我編寫了一個簡單的泛型。

這有效並且真正消除了一堆重復的代碼,但感覺很笨,而且語法非常遲鈍。 每次我回到這里,我的大腦都會扭曲,試圖找出它(一個明顯的標志,這不是一個好的設計)。 我正在尋找關於這是否是一件瘋狂事情的​​反饋,以及是否有更好的方法來解決它。

這是我的模板:

public delegate T2 RestfulServiceRequest<T1, T2>(T1 req);

static class RestfulService
{
    public static T2 ExceptionHandler<T1, T2>(RestfulServiceRequest<T1, T2> serviceCall, T1 req)
    {
        if (req == null)
           throw new BadRequestException(new ArgumentNullException("Invalid or missing request object"));

        try
        {
            return serviceCall(req);
        }
        catch (RestfulException e)
        {
            // log it and rethrow
            Logger.Write(e);
            throw;
        }
        catch (Exception e)
        {
            Logger.Error(e);

            // wrap in a consistent exception for propagation back to caller
            throw new InternalServerException(e);
        }
        finally
        {
            Logger.Debug("Complete");
        }
    }
}

}

以下是它的用法:

public class Initialization : IInitialization
{
    // MyMethod thas uses the template
    public ApplianceInitResp CreateApplianceServer(ApplianceInitReq req)
    {
        return RestfulService.ExceptionHandler<ApplianceInitReq, ApplianceInitResp>(delegate(ApplianceInitReq x)
        {
            // do some work
            return new ApplianceInitResp();
        }, req);
    }
}

}

我會改變

public static T2 ExceptionHandler<T1, T2>(RestfulServiceRequest<T1, T2> serviceCall, T1 req)

public static T2 Invoke<T1, T2>( this T1 req, RestfulServiceRequest<T1, T2> serviceCall)

這會將通話更改為

public class Initialization :IInitialization {
    public ApplianceInitResp CreateApplianceServer( ApplianceInitReq req ) {
        return req.Invoke( r => {
            // do some work
            return new ApplianceInitResp();
        });
    }
}

使其更清晰的一件事是定義請求/響應對象實現的接口。 然后你就可以擺脫泛型,轉而使用接口。 請注意,我認為名稱更改更能描述您真正想要做的事情。

public interface IServiceResponse { ... }
public class ApplianceInitResp : IServiceResponse { ... }
public interface IServiceRequest { ... }
public class ApplianceInitReq : IServiceRequest { ... }

public delegate IServiceResponse RestfulServiceRequest( IServiceRequest req );

static class RestfulService
{
    public static IServiceResponse
        Invoke( RestfulServiceRequest serviceCall, IServiceRequest req)        
    {
        if (req == null)
            throw new BadRequestException( ...inner-exception... );
         try
         {
            return serviceCall(req);
         }
         catch (RestfulException e)
         {
            Logger.Write(e);
            throw;               
         }
         catch (Exception e)
         {
             Logger.Error(e);
             throw new InternalServerException(e);
         }
         finally
         {
             Logger.Debug("Complete");
         }
    }
}

public class Initialization : IInitialization
{
     // MyMethod thas uses the template 
     public ApplianceInitResp CreateApplianceServer(ApplianceInitReq req) 
     {
          return RestfulService.Invoke(
                    delegate(ApplianceInitReq x)
                    {
                        // do some work
                        return new ApplianceInitResp();
                    },
                    req );
     }
}

我建議你尋找提供AOP功能的框架(如Spring.NET,Unity)。 這些將幫助您減少CreateApplianceServer()調用

public ApplianceInitResp CreateApplianceServer(ApplianceInitReq req)
{
    // Do some work
    return new ApplianceInitResp();
}

通過處理入口/出口和異常日志記錄與方面。 也許,如果你有一些常見的參數,你也可以將參數驗證插入方面。

當然,會有學習曲線稅,但是,相信我,結果值得。 您將大大減少方法中的樣板代碼量。

我同意這感覺有點笨拙,但是,我並沒有立即看到重復工作的“完美”方式,以盡量減少重復。

我唯一想到的是,如果你能以某種方式使用接口或稍微分解一下,我不確定我是怎么做的,但是我可以說,對於正在進行的改變我不認為我會離開這個,至少沒有真正好的文檔。

我覺得你做的很好。 這種編碼在腳本語言中很常見 - 但由於它們是動態類型的,所以它不那么冗長。 它在函數式語言中也很常見 - 但它的冗長程度更低,因為它們具有如此好的類型推斷! 在C#中,你受到類型推理系統當前局限性的限制,但在版本4中會更好。

另一種方法是使用大量的接口或類來封裝您的工作。 在執行此操作時,您在調用時具有較少的類型名稱,但整體代碼更多。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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