没有太多通用参数的C#代码重用

问题描述 投票:0回答:2

我有一个叫做CommercialRiskProcessor的课程。它只有221行,包括注释和using。它只有3个注入参数,并且只做一件事-评估一些风险。实际上,它的接口只有一种方法:

public interface ICommercialRiskProcessor
{
    Task<CommercialQuoteWithStatus> ApplyRules(CommercialRiskProcessorRequestInfo info, CommercialQuoteContext qtx, EFCommercialQuote quote);
}

因此,无论如何,它不是“神”类。它开始如下:

public class CommercialRiskProcessor : ServiceBase, ICommercialRiskProcessor
{
    public const string UiHardDeclineMessage = WorkflowFailure.UiDefaultWorkflowFailureMessage;
    protected ICommercialRiskRuleCollectionFactory RiskRuleCollectionFactory { get; }
    protected ICommercialRiskRuleFactory RiskRuleFactory { get; }
    protected ICommercialOverrideService OverrideService { get; }

    public CommercialRiskProcessor(
        ICommercialRiskRuleCollectionFactory riskRuleCollectionFactory,
        ICommercialRiskRuleFactory riskRuleFactory,
        ICommercialOverrideService overrideService)
    {
        RiskRuleCollectionFactory = riskRuleCollectionFactory;
        RiskRuleFactory = riskRuleFactory;
        OverrideService = overrideService;
    }

    public async Task<CommercialQuoteWithStatus> ApplyRules(CommercialRiskProcessorRequestInfo info, CommercialQuoteContext qtx, EFCommercialQuote quote)
    {
        var ruleCollection = await RiskRuleCollectionFactory.TryResolveService(info.RuleCollectionName, qtx, quote);

        if (ruleCollection == null)
        {
            return new CommercialWorkflowFailure(UiNotSupportedStateMessage);
        }

        var results = await ApplyRules(ruleCollection, qtx, quote);
        qtx.RuleEvaluationResults.AddRange(results);
        return await ProcessResults(info, results, qtx, quote);
    }

并且有一些私有方法可以进行一些额外的处理。这无关紧要。问题是我需要另一个风险处理程序,称为HomeownerRiskProcessor。如果我复制/粘贴整个文件,然后将“ Commercial”重命名为“ Homeowner”,则新类将立即可用,因为在这两组类中所有支持类和属性都被相同地调用。然而,房主和商业阶层是非常不同的,因此所有底层对象都是不同的。

因此,复制/粘贴/单次替换似乎不是一种好的编码样式,不是吗?然而,利用代码重用的唯一可能方法似乎是引入泛型。这是一团糟的地方:风险处理器类中使用的每个方法/属性都必须经过generic化,并引入了一些通用的通用接口。随后,使整个类成为通用类(包括私有成员)将需要10个以上带有多个通用约束的通用参数!显然,这远远超出了可读性,可能会使其比复制/粘贴/修改更糟。

我想知道是否还有其他解决方案可以实现代码重用,但是在单个代码中没有太多的通用参数。

c# generics code-reuse
2个回答
0
投票

如果我复制/粘贴整个文件,然后将“ Commercial”重命名为“房主”,那么新类将立即可用,因为所有在这些中,支持类和属性的名称相同两组班。然而,房主和商业阶层非常不同,因此所有基础对象都不同。

听起来,即使这些类非常不同,您也可以从它们中提取相同的接口。您只需要将接口限制为仅风险处理所需的方法即可。然后,风险处理器可以对实现这些接口的任何类进行操作。

这里不需要泛型。


0
投票

下面的代码对您有用吗?基本上,您对接口所做的全部工作就是设置一个模板,该模板必须至少遵循该模板。

public interface IRiskProcessor<TQuoteWithStatus, TRiskProcessorRequestInfo, TQuoteContext, TEFQuote>
{
    Task<TQuoteWithStatus> ApplyRules(TRiskProcessorRequestInfo info, TQuoteContext qtx, TEFQuote quote);
}

public interface ICommercialRiskProcessor : IRiskProcessor<CommercialQuoteWithStatus, CommercialRiskProcessorRequestInfo, CommercialQuoteContext, EFCommercialQuote>
{
    Task<CommercialQuoteWithStatus> ApplyRules(CommercialRiskProcessorRequestInfo info, CommercialQuoteContext qtx, EFCommercialQuote quote);
}

public interface IHomeOwnerRiskProcessor : IRiskProcessor<HomeOwnerQuoteWithStatus, HomeOwnerRiskProcessorRequestInfo, HomeOwnerQuoteContext, EFHomeOwnerQuote>
{
    Task<HomeOwnerQuoteWithStatus> ApplyRules(HomeOwnerRiskProcessorRequestInfo info, HomeOwnerQuoteContext qtx, EFHomeOwnerQuote quote);
}
© www.soinside.com 2019 - 2024. All rights reserved.