c# – 如何减少此代码中的耦合

在工作中,我正在执行此应用程序,该应用程序从外部文件(Excel工作表,文本文件……)中获取值,并将这些值转换为复杂的指令,这些指令将输入到另一个系统中.

下面的代码有点简化(没有指令和非常简单的逻辑),但这个想法保持不变.我有大约60个不同的翻译人员,他们背后有不同的业务逻辑.有些只运行一个参数.其他人则提出多个论点

我有一个抽象的翻译班.该类的用户将使用2个公共方法:Translate运行转换逻辑,CanTranslate允许查看转换器是否已准备好启动.

使用此抽象类的开发人员需要实现DoTranslate方法,该方法将包含实际的业务逻辑.默认情况下,CanTranslate始终返回true,但如果需要验证,则可以覆盖它.

这是抽象翻译基类:

// Contains some base logic which is the same for all translators
public abstract class BaseTranslator
{
    // Public translate method
    public void Translate()
    {
        if (CanTranslate())
            DoTranslate();
    }

    // Checks if we are ready to translate
    // True by default
    public virtual bool CanTranslate()
    {
        return true;
    }

    // This method is used to implement business logic
    public abstract void DoTranslate();
}

这是一个具体的翻译类的实现:

// Translates beer names
public class ReverseTranslator : BaseTranslator
{
    // Use of properties to allow strongly typed arguments
    // which can be seen by the developer at design time
    public string BeerName { get; set; }

    // Validation
    public override bool CanTranslate()
    {
        if (BeerName.Equals("Budweiser") || BeerName.Equals("Stella"))
            return true;
        else
            return false;
    }

    // Implementation of the business logic
    public override void DoTranslate()
    {
        char[] letters = BeerName.ToCharArray();
        Array.Reverse(letters);
        Console.WriteLine(new string(letters));
    }
}

以下是使用时的样子:

class Program
{
    public static void Main(string[] args)
    {
        var translator = new ReverseTranslator();

        translator.BeerName = "Stella";
        translator.Translate();

        translator.BeerName = "I'm not a beer";
        // This line will not translate since it's not a valid beer name.
        translator.Translate();

        Console.ReadLine();
    }
}

Pro的:

>以小型可维护单元分隔特定业务逻辑
>翻译器易于在应用程序的其他部分重用
>翻译人员可以轻松进行单元测试
>属性允许翻译用户查看所需的参数

我的问题:

>不同的控制器类正在使用许多翻译器.我有太多的耦合.

我想过将Factory模式用于翻译器创建,但是我不能在设计时使用属性作为参数提示.

所以我基本上在寻找一种解决方案,在设计时你可以很容易地看到需要哪些参数.同时我希望通过不让每个控制器拥有30个新的xTranslator语句来减少耦合.

PS:我只限于使用.NET 3.5代码.

最佳答案 要获得具体类的特定参数的设计时信息:您需要使用具体类的实例.

要减少控制器中的耦合:您需要限制自己的抽象类实例.

你不能同时在同一个地方.

重新设计整体设计可以消除耦合并消除对设计时间信息的需求.

将转换器的创建和初始化从控制器移到工厂或IoC容器中,该容器将来自外部文件的一行数据作为输入(如果需要,可以按照它可以使用的格式进行按摩).

让翻译者需要一个带有参数集合的构造函数.
优点:

>只有具体类本身需要了解有关自身的细节
它的参数.
>工厂需要有关哪种翻译人员在哪种情况下使用的信息.

.

class TranslatorFactory
{
    //translator lookup table
    private Dictionary<string, Func<List<string>,BaseTranslator>> Translators = 
        new Dictionary<string,Func<List<string>,BaseTranslator>>{
            {"Reverse", (args)=>new ReverseTranslator(args)},
            {"Explode", (args)=>new ExplodeTranslator(args)}        };

    public BaseTranslator GetTranslatorForRow(string command, List<string> arguments)
    {
        if(Translators.ContainsKey(command) )
        {
             return Translators[command](arguments);
        }
        return null; //or default, or throw exception
    }
}


abstract class BaseTranslator
{
    ...
    public BaseTranslator(List<string> args)
    {
    }
}

class ReverseTranslator: BaseTranslator
{
    public string BeerName {get;set;}
    public ReverseTranslator(List<string> args)
    {
        BeerName = args[0];
    }
}

您可以进一步使用属性和反射删除工厂和具体类之间的耦合,以动态构建查找表.

[TranslatorFor("Reverse")]
class ReverseTranslator: BaseTranslator
{
    ...
}
点赞