输出计算策略问题

时间:2011-07-30 10:17:10

标签: c#

也许不是我能想到的最好的头衔,但我的问题是:

我必须设计一个C#应用程序,它接受一堆输入,根据一堆规则对输入执行一些计算,以获得一组结果。

问题在于规则可以根据需要进行更改。使事情复杂化,其中许多是交叉表查找和条件。例如,

public string rule_GetFruitForThisSeason(Hamper design)
{
    // crosstab of 2 properties of values 400 to 100 and 600 to 500 respectively.
    if(design.pty1 > 400 && design.pty > 600) return "Apple";
    else if(design.pty1 > 200 && design.pty > 600) return "Pear";
    else if(design.pty1 > 100 && design.pty > 600) return "Orange";
    else if(design.pty1 > 400 && design.pty > 500) return "Grape";
    else if(design.pty1 > 200 && design.pty > 500) return "Berry";
    else if(design.pty1 > 100 && design.pty > 500) return "Peach";
}

然后在下一季,所有的水果可能会再次变化! (即使是条件也可能会改变。)理想情况下,我不希望程序员每个季节都能改变成果。礼篮设计师应该能够自己做。

更糟糕的是,可能存在依赖于输出的规则,例如

public string rule_GetBoxForFruit(string fruit)
{
   if(fruit == "Apple" || fruit == "Pear" || fruit == "orange" || fruit == "peach") return "big box";
   else return "small box";
}

我一直在思考各种方法,目前我正在使用excel进行LOOKUP(),并且通常能够评估公式,然后直接读取excel结果。但这仍然是一项繁重的任务。

任何人对如何以更好的方式解决这个问题都有任何想法?谢谢。

1 个答案:

答案 0 :(得分:0)

您可以通过多种方式解决此类问题,但主要概念是将数据与代码分开。这样做的一种方法是将规则封装到XML文件中,然后使用XML文件中的值来管理逻辑。例如,以下文件可能包含您的所有规则:

<configuration>
    <hamper>
       <seasonalRules>
          <!-- select first rule where 
               design.pty1 > pty1 and design.pty2 > pty2
          -->
          <rule pty1="400" pty="600" fruit="apple" />
          <rule pty1="200" pty="600" fruit="pear" />
          <rule pty1="100" pty="600" fruit="orange" />
          <!-- similar for remaining -->
       </seasonalRules>
    </hamper>
    <fruits>
       <fruit name="apple" box="smallBox" />
       <fruit name="berry" box="smallBox" />
    </fruits>
    <boxes>
       <box name="smallBox" size="small" />
       <box name="largeBox" size="large" />
    </boxes>
</configuration>

然后你可以使用XML到Linq(或任何XML API)来读取文件并执行你的逻辑:

// ConfigurationData is loaded as
// XDocument.Load("file.xml").Root

public string rule_GetFruitForThisSeason(Hamper design)
{
        var node = ConfigurationData.Elements("hamper")
            .Elements("seasonalRules")
            .Elements("rule")
            .Where(a => int.Parse(a.Attribute("pty1").Value) > design.pty1 &&
                        int.Parse(a.Attribute("pty").Value) > design.pty)
            .FirstOrDefault();
        if (node == null) return null;
        return node.Attribute("fruit").Value;
}

由于此代码比较了业务常量,因此XML文件中的配置常量可以更改,而无需更改相应的代码。您还可以开发一个实用程序,将配置数据保存到XML文件中,篮子设计人员可以使用它来更改计算规则。