首页 > 解决方案 > C#。如何灵活提取常用逻辑

问题描述

我有两个类,A和B。它们有很多共同的逻辑,但是这种逻辑在某些地方是不同的,例如:

CommonLogicClass {
    CommonMethod() {
        common1
        different1
        common2
        different2
    }
}

我不相信存在最好的方法,但只想知道哪些方法是可能的。

我发现只有两种相似的方法:将不同的部分传递给CommonLogicClass的构造函数或使A和B实现接口并实现方法Different1()和Different2(),然后使用接口代替不同的部分。

这些方法存在一些问题。当我使用相同的方法创建 3-d 类 C 时,我可能需要一个附加部分,如下例所示:

CommonMethod() {
    common1
    different1
    common2
    different2
    additionalCodeOnlyForCClass
}

在这种情况下,我将不得不添加空操作或向接口添加方法,并将其作为空方法在除 C 之外的所有类中实现。

或者,当 common2 仅对 A 和 B 通用但对 C 不通用时,我可能会遇到更糟糕的情况:

CommonMethod() {
    common1
    different1 \
    different2 - (or just different1)
    different3 /
}

我需要从 common 中排除 common2,使其不同,并为除 C 之外的所有类添加相同的代码。

因此,当更改或添加最少的逻辑时,总会有很多更改。还有哪些更灵活的方法可以提取通用逻辑?也许有一些我应该学习的模式或者我应该阅读一些书来回答关于这样的架构的问题?

标签: c#architecturerefactoring

解决方案


我想您可能正在寻找模板方法模式:https ://en.wikipedia.org/wiki/Template_method_pattern

创建一个实现通用功能的抽象基类。在子类中实现差异。

void Main()
{
    LogicBase a = new ClassA();
    a.CommonMethod();

    Console.WriteLine("----------------------------");

    LogicBase b = new ClassB();
    b.CommonMethod();
}

public class LogicBase
{
    public void CommonMethod()
    {
        DoSomething_1();
        DoSomething_2();
        DoSomething_3();
    }

    protected virtual void DoSomething_1()
    {
        // Default behaviour 1
        Console.WriteLine("DoSomething_1 - Hello from LogicBase");
    }

    protected virtual void DoSomething_2()
    {
        // Default behaviour 2
        Console.WriteLine("DoSomething_2 - Hello from LogicBase");

    }

    protected virtual void DoSomething_3()
    {
        // Default behaviour 3
        Console.WriteLine("DoSomething_3 - Hello from LogicBase");
    }
}

public class ClassA : LogicBase
{
    protected override void DoSomething_2()
    {
        // Behaviour specific to ClassA
        Console.WriteLine("DoSomething_2 - Hello from ClassA");
    }
}

public class ClassB : LogicBase
{
    protected override void DoSomething_3()
    {
        // Behaviour specific to ClassB
        Console.WriteLine("DoSomething_3 - Hello from ClassB");
    }
}

运行代码给出以下输出:

DoSomething_1 - Hello from LogicBase
DoSomething_2 - Hello from ClassA
DoSomething_3 - Hello from LogicBase
----------------------------
DoSomething_1 - Hello from LogicBase
DoSomething_2 - Hello from LogicBase
DoSomething_3 - Hello from ClassB

推荐阅读