重复代码模式

本文关键字:模式 代码 | 更新日期: 2023-09-27 18:21:38

我有特定的代码模式(记录每个函数的性能和其他变量),需要出现在每个函数中,我不想一遍又一遍地重复代码。以下是代码的样子:

public OutClass FUNC-X
{
 if (IsDebugEnabled)
    {
        Logger("Start DataLibrary: FUNC-X");
    }
try
{
    CheckInitSucceeded();
    GetAuthenticationTokens();
    var dm = new Manager();
    /**
    * THIS SINGLE LINE IS THE VARIABLE PART
    **/
    var output = dm.FUNC-X(...);
    if (IsDebugEnabled)
    {
        var data = Serialize(output);
        Logger(output);
    }
    return output;
}
catch (WebFaultException)
{
    throw;
}
catch (OtherException ex)
{
    if (Logger.IsErrorEnabled)
    {
        Logger.LogError("Exception in FUNC-X", ex);
    }
    throw new OtherException("Some Message");
}
catch (Exception ex)
{
    if (IsErrorEnabled)
    {
        Logger("Exception in FUNC-X", ex);
    }
    throw new Exception("Generic Exception");
}
finally
{
    if (IsDebugEnabled)
    {
        Logger("End FUNC-X");
    }
    }
}

本质上,我只需要用FUNC-Y或FUNC-Z代替FUNC-X,无论这个名字出现在哪里,我都可以遵循某种设计模式吗?

如果问题含糊不清,我很抱歉,我很乐意提供你所问的任何细节。

重复代码模式

是的,有很多方法可以提供漂亮的日志代码。

  1. 使用面向方面的编程。有PostSharp和Spring.NET。您可以使用log4net库。config之后的所有方法都支持写入方法名。

  2. 您可以在编译之前使用T4并为所有函数生成代码。

  3. 您可以编写一个接受Func<object> methodstring methodName的全局日志记录方法。假设您将日志记录方法命名为LogAndExecute。然后打电话你必须写smth像:

    LogAndExecute("func-x", () => dm.Func-X(/*your args*/))
    

    如果您在函数的不同返回类型上遇到问题,请使用泛型

您可以使用简单委托接受可变部分作为参数(如果单行函数调用的参数数量相同)

    public void Function_X(Func<object,..> func)
    {
        if (IsDebugEnabled)
        {
                Logger("Start DataLibrary: FUNC-X");
        }
        try
        {
            CheckInitSucceeded();
            GetAuthenticationTokens();
            var dm = new Manager();
            /**
            * THIS SINGLE LINE IS THE VARIABLE PART
            **/
        //    var output = dm.FUNC-X(...);
            var output = func(...);
            if (IsDebugEnabled)
            {
                var data = Serialize(output);
                Logger(output);
            }
            return output;
        }
        catch (WebFaultException)
        {
            throw;
        }
        catch (OtherException ex)
        {
            if (Logger.IsErrorEnabled)
            {
                Logger.LogError("Exception in FUNC-X", ex);
            }
            throw new OtherException("Some Message");
        }
        catch (Exception ex)
        {
            if (IsErrorEnabled)
            {
                Logger("Exception in FUNC-X", ex);
            }
            throw new Exception("Generic Exception");
        }
        finally
        {
            if (IsDebugEnabled)
            {
                Logger("End FUNC-X");
            }
        }
    }

您可以创建一个接受Func委托的通用函数:

    static public TOutClass CommonFunc<TOutClass>(Func<Manager, TOutClass> func)
    {
        if (IsDebugEnabled)
        {
            Logger("Start DataLibrary: FUNC-X");
        }
        try
        {
            CheckInitSucceeded();
            GetAuthenticationTokens();
            var dm = new Manager();
            TOutClass output = func(dm);
            if (IsDebugEnabled)
            {
                var data = Serialize(output);
                Logger(output);
            }
            return output;
        }
        catch
            [...]
    }

你会把你的函数写成:

public OutClass FUNC-X(...)
{
   return CommonFunc(dm=>dm.FUNC-X(...));
}