将公共方法转换为扩展方法

时间:2010-10-14 18:15:24

标签: c# extension-methods public-method

在我的项目的核心库中,我们有一个非常大的类,它倾向于成为God object。其中一个原因是,在一段时间内,应该在不同模块中的任务已被纳入本课程。对于前 -

class HugeClass{
    public void DoModuleXJob(){}
    public void DoModuleYJob(){}
}

重构和移动不需要的模块特定行为的问题之一是模块X和模块Y更改其代码将需要做很多工作。 作为一种解决方法,我正在考虑将这些方法转换为扩展方法,然后将它们移动到相关的模块中。对于前 -

// in module X
static class HugeClassExtensions{
    public static void DoModuleXJob(this HugeClass instance){}
} 

// in module Y
static class HugeClassExtensions{
    public static void DoModuleYJob(this HugeClass instance){}
}

我发现这不会产生任何编译问题,只要模块Y没有使用DoModuleXJob,反之亦然,我相信。

这是一个很好的解决方案吗?在这种情况下有没有更好的方法?

4 个答案:

答案 0 :(得分:1)

这不是一个糟糕的中间步骤,因为它至少为您提供了一种分区功能并证明扩展“模块”之间没有方法相互依赖关系的方法。这是创建真正的子类的第一步,虽然它仍然不理想(你无法单独为单元测试实例化模块类。)

一旦进行了这种分区,就可以更容易地创建新类,因为您已经确定了模块边界。这个过程会是这样的:

  1. 传递给扩展方法的参数成为新类的一个字段,该字段在构造函数中设置。

  2. 所有扩展方法都成为新类的方法。

  3. 您现在可以提取主类的接口,因此子类不再依赖于完整实现。在某些情况下,您可以通过将功能分解为多个接口来进一步减少依赖性

  4. 现在您已通过接口进行依赖关系隔离,您可以为各个模块编写单元测试。

答案 1 :(得分:0)

扩展方法只是一种“语法糖”。您可以定义公共静态方法,并使HugeClass实例成为其中一个参数。 所以没有区别。编译后的CIL文件将是相同的。

答案 2 :(得分:0)

我看到你的设计不同,但为什么你没有使用Workflow Foundation 4.0?它简单灵活。您可以在工作流程中将代码编写为CodeActivity。我认为您可以将工作流程(Activity)假设为可以添加到核心的新模块作业。

您可以动态生成非常有用的工作流程(活动)。

(对不起我的英语不好)

答案 3 :(得分:0)

我建议您按原样创建设计,将HugeClass中的功能移动到应该的位置,然后将方法调用留在HugeClass中,但是让它遵循功能到它的位置移动:

class HugeClass
{
    [Obsolete("Use ModuleX.DoModuleXJob() instead", false)]
    public void DoModuleXJob() {
        ModuleX mod = new ModuleX();
        mod.DoModuleXJob();
    }
}
class ModuleX
{
    public void DoModuleXJob() {
    }
}

这样,随着时间的推移,您将Facade Pattern与HugeClass一起使用。我已经应用于HugeClass方法的Obsolete attribute意味着每次编译调用HugeClass中的方法的内容时,都会生成警告,指向新功能的位置。属性中的'false'参数是使其成为警告的原因,可以将其更改为true以使其成为错误。通过这种方式,你没有做太多额外的工作,它代表了你想要的进展,我不相信你的扩展方法技术必然会做。随着时间的推移,可以删除HugeClass中的方法,直到它是一个空类,并且可以删除它。

很明显,如果你还没有读过Martin Fowler的书Refactoring,这是一本很好的读物。在其中,他讨论了这个和许多其他技术。