优雅的数字 - >字母学术等级映射

时间:2014-03-31 20:42:19

标签: .net oop design-patterns mapping range

这是一个我想开始公开问题的简单示例。

考虑一下你有一堆数字,从0到10,你想把它们映射到字母等级(A,B,C,D,F)。

可以编写一系列if语句,测试相应字母范围内的给定数字并返回正确的字母。

问题是:可以使用什么模式来使其更加健壮并且可能更加分离?例如,如果不是5个数字范围而是10个,我将不得不编辑这个单片方法来添加其他5个案例。我也不能保证我的范围是独家的,即使它们应该是这种情况。

我可以想象这里使用了Dictionary<Range<int>, string>>种类,但它似乎还不足以提供我正在寻找的所有保证。也许可以使用多态来以更简化和可扩展的方式对这个概念进行建模?

我很抱歉这个简单的例子,但我确信这可以作为一种通用的范围映射策略应用于其他更复杂的算法。

1 个答案:

答案 0 :(得分:1)

如果将位置映射到位置线性增加并且结果增加相同数量的其他格式那么简单,则可以使用简单的公式。

对于您的成绩单示例,映射&#39; A&#39;到0,&#39; B&#39;到1等就是:

int value = ...
Character result = value -'A';

大多数语言都会映射&#39; A&#39;到它的ASCII值,从而减去你想要的值&#39; A&#39;将产生字母数量&#34;过去&#34;甲

如果您需要更复杂的内容,例如范围映射,那么Replace Conditional Dispatcher with Command模式(示例显示为here)可能是一个好主意。

如果你有更复杂的东西,那就像Chain of Responsibility Pattern。

这是一个简单的例子:

您需要创建一个具有方法的接口,以确定您提供的Range是否适用于该实现。

IGradeMapper{
   bool accept(Range<int>);

   String computeGrade(Range<int>);
}

然后你有一个按顺序检查的IGradeMapper列表:

for(IGradeMapper mapper : list){
    if(mapper.accept(range)){
        return mapper.computeGrade(range);
    }
}

关于这种方式的好处是匹配器每个都是loosley耦合的,如果你愿意的话,你可以稍后(甚至在运行时)实现并添加新的列表。

如果您使用其中任何一种模式,那么请尝试使第一个测试条件最常用,以使其运行得更快。