具有不同等级系统的等级的良好模式

时间:2015-10-27 10:02:21

标签: design-patterns

我正在建立一个可以评分的考试系统,但问题是它们可以在不同的评分系统中评分(如A,B,C,D ......或百分比或12,10,我们在丹麦使用的7,4,20,000系统。

我需要一些方法来对成绩进行统计,因此不能简单地将它们存储为字符串。

我希望能够轻松制作新的评分系统。

我正在考虑制作IGradeSystem接口和Grade类(引用IGradeSystem)。这样我就可以简单地为新等级系统制作新的接口实现。但我不知道这是否是一个很好的方法。

我应该使用什么模式的指针?我确信有一个很好的/可接受的方式,我更喜欢使用模式。

2 个答案:

答案 0 :(得分:1)

这些只是具有最小值,最大值以及将“原始值”转换为人类可读值的方法。

假设您有一个泛型类,它将等级存储在从0到1的浮点数中,然后子类有一个方法将浮点数转换为“等级系统”:

  • 乘以100 - >百分比
  • 乘以20然后舍入到最接近的.5 - >法国商标(0至20)
  • 乘以5,舍入,然后按相反顺序分配字母(A = 5,B = 4,...,F = 0)

答案 1 :(得分:1)

您的IGradeSystem解决方案是一个良好的开端。您可以将其用作Grade中的一种策略/策略设计模式,以将该等级转换为其他系统。泛型是一种很好的方法,可以抽象出等级所具有的价值类型(整数,字母等)以及它所处的等级系统。

我可以创建一个可以作为兼容等级系统之间的支点的通用等级系统,而不是拥有可以从任何等级系统转换为任何其他等级的无所不知的策略。如果所有等级系统都知道如何将其领域中的值转换为公共系统,则转换操作可以简单如下:

TargetGradeSystem.From(MyGradeSystem.To(CommonGradeSystem))

这是一个单元测试,展示如何从客户端代码角度使用它:

    [TestMethod]
    public void GradeTest()
    {
        var grade1 = new CharacterGrade('A', GradeSystems.Letters);
        var grade2 = new NumericGrade(100, GradeSystems.Percentage);

        Assert.AreEqual(grade2.Value, grade1.To<int, PercentageGradeSystem>().Value);
    }

可以像这样定义等级系统类型,在添加新系统时允许最小的摩擦力:

public abstract class GradeSystem<TValue, TCommon>
{
    public abstract Grade<TCommon, TCommon> ToCommon(TValue value);
    public abstract Grade<TValue, TCommon> FromCommon(Grade<TCommon, TCommon> common);
}

public class LetterGradeSystem : GradeSystem<char, int>
{
    // assuming Percentage is the common system
    public override Grade<int, int> ToCommon(char value)
    {
        var index = char.ToUpper(value) - 64;
        return new Grade<int, int>(100 - ((1 - index) * 20), GradeSystems.Percentage);
    }

    public override Grade<char, int> FromCommon(Grade<int, int> common)
    {
        var character = (char)(common.Value + 64);
        return new Grade<char, int>(character, GradeSystems.Letters);
    }
}

如果你想查看代码,我用其余的代码创建了一个要点:https://gist.github.com/infosaurus/18d216ddf471c9619f7d