您是否会使用Action委托来避免重复代码?

时间:2010-04-28 18:43:49

标签: dry

我刚问了一个有助于使用泛型(或多态)来避免重复代码的问题。我真的想遵循DRY原则。

所以我刚刚遇到以下代码......

Sub OutputDataToExcel()

        OutputLine("Output DataBlocks", 1)
        OutputDataBlocks()
        OutputLine("")

        OutputLine("Output Numbered Inventory", 1)
        OutputNumberedInventory()
        OutputLine("")

        OutputLine("Output Item Summaries", 1)
        OutputItemSummaries()
        OutputLine("")

End Sub

我是否应该使用Action delegate ...

将此代码重写为如下所示
Sub OutputDataToExcel()
    OutputData("Output DataBlocks", New Action(AddressOf OutputDataBlocks))
    OutputData("Output Numbered Inventory", New Action(AddressOf OutputNumberedInventory))
    OutputData("Output Item Summaries", New Action(AddressOf OutputItemSummaries))
End Sub

Sub OutputData(ByVal outputDescription As String, ByVal outputType As Action)
    OutputLine(outputDescription, 1)
    outputType()
    OutputLine("")
End Sub

我意识到这个问题是主观的。我只是想知道你是如何虔诚地遵循DRY。你会这样做吗?

赛斯

2 个答案:

答案 0 :(得分:4)

我看到这个被称为“中间的洞”模式。 “真实世界功能编程”一书提到了它。这是一个链接。

http://enfranchisedmind.com/blog/posts/the-hole-in-the-middle-pattern/

  

看,有一种模式我已经得到了   曾经在Ocaml-我甚至使用它   在Perl,我认为是“洞   在中间的“模式。基本的想法   是你有两段代码   几乎完全相同,   除了那个小中间部分   那里。这个想法是你要分解出来的   将公共代码合并为一个   功能,需要一个功能   指针作为参数。中间   共享代码中的部分替换为   调用函数指针,和   正在存在的两个地方   结合只需调用组合   带有指向函数的指针的函数   包含独特的部分。

答案 1 :(得分:1)

我不会说我一直都在使用它,但我使用了Action委托来避免代码重复。我使用它的一个场景是包装WCF调用(在客户端代理内)以避免使用相同的样板代码。

   private void InvokeAndHandleFaults(
        Action<Data, Context> wcfCall,
        Data data,
        Context context)
    {
        bool isSuccess = false;

        try
        {
            wcfCall(data, context);

            if (this.ChannelFactory.State != System.ServiceModel.CommunicationState.Faulted)
            {
                this.ChannelFactory.Close();
            }

            isSuccess = true;
        }
        catch (FaultException ex)
        {
            HandleFault(ex);
        }
        finally
        {
            if (!isSuccess)
            {
                this.ChannelFactory.Abort();
            }
        }
    }

就问题中的示例而言,我可能不会使用Action。我肯定不会重构使用Action。主要是因为实际的逻辑非常简单所以我没有看到太多的好处。随着重复代码的“复杂性”/大小的增加,我更有可能使用委托。