什么设计决策更适合计算预测和评分系统?

时间:2011-07-07 22:00:24

标签: c# architecture c#-4.0 software-design

我正在尝试制作一个应用程序,让用户根据预测和实际结果填写预测和得分。

我有这个名为GetPointsPrediction()的方法。目前,预测具有以下形式:

Dictionary<int, Driver> predictions = new Dictionary<int, Driver>
{
    {1, new Driver(10, "Michael Schumacher")},
    {2, new Driver(8, "Jensen Button")},
    {3, new Driver(7, "Felipe Massa")},
    {4, new Driver(9, "Fernando Alonso")}
};

整数是用户认为驾驶员将完成的位置。现在,我需要能够根据预测和结果计算点数。为了给出分数,我需要在结果中输入三条信息:位置,驱动程序和点。

完全处于预测位置的车手获得满分。没有在预测位置完成但排在前十位的驾驶员会减少积分。

您看到的所有序号都是位置。

解决方案编号1:

有一个单独的结果集,以及一个包含每个位置的字典的字典,用作查找:

Dictionary<int, Driver> results = new Dictionary<int, Driver>
{
    {1, new Driver(10, "Michael Schumacher")},
    {2, new Driver(8, "Jensen Button")},
    {3, new Driver(9, "Fernando Alonso")}
};

Dictionary<int, int> points = new Dictionary<int, int>
{
    {1, 25},
    {2, 18},
    {3, 15},
    {4, 12},
    {5, 10}
};

解决方案编号2:

合并点和结果。

Dictionary<int, Dictionary<int, Driver>> results = new Dictionary<int, Dictionary<int, Driver>>

解决方案编号3:

提出一些可以掌握一切的课程:

public class DriverResult
{
    public Driver Driver { get; private set; }
    public int Points { get; private set; }
    public int StartPosition { get; private set; }
    public int FinishPosition { get; private set; }
}

然后

IEnumerable<DriverResult> raceResults = new List<DriverResult>

我喜欢3号解决方案,但我觉得它不够连贯,而且名字感觉也不好。解决方案2可能难以真正使用,解决方案1实际上为我提供了一个很好的方法来将正确预测的驱动程序与Intersect分开。

也许我还没有想到其他一些解决方案。有关这些设计决策的最佳做法是什么?

Driver类:

public class Driver : IEquatable<Driver>
    {
        public int DriverId { get; private set; }
        public string Name { get; private set; }

        public Driver(int driverId, string name)
        {
            DriverId = driverId;
            Name = name;
        }

        public override bool Equals(object obj)
        {
            return Equals(obj as Driver);
        }

        public bool Equals(Driver other)
        {
            return other != null && other.DriverId == DriverId;
        }

        public override int GetHashCode()
        {
            return DriverId.GetHashCode();
        }
    }

1 个答案:

答案 0 :(得分:0)

由于预测按位置顺序排列,因此它们应该是一个数组。由于点也是按顺序的位置,因此也应该是一个数组。使用字典没有任何意义。但是,如果要按ID查找驱动程序,则需要创建驱动程序的Dictionary或SortedList,其中ID为关键,而不是顺序的位置。所以你有两个数组:

Driver[] predictions = new Driver[]
{
    new Driver(10, "Michael Schumacher"),
    new Driver(8, "Jensen Button")
    new Driver(7, "Felipe Massa")
    new Driver(9, "Fernando Alonso")
};

位置为-1的索引,例如预测[0]是位置1的预测。类似地,使用数组作为点:

int[] points = new int[] { 25, 18, 15, 12, 10 };

按位置访问点 - 1,例如points [0]是位置1的点。

考虑将DriverPoints和StartPosition等其他字段添加到Driver,而不是使用DriverResults。然后你可以只更新数组中的Driver类。

编辑:要存储各种种族,测试,季节等结果,请创建一个名为DriverResults的类,并使用RaceResults或SeasonResults等类继承它。将成员添加到驱动程序:

List<DriverResults> Results { get; set; }

现在您可以创建SeasonResults或RaceResults并将它们添加到此列表中,存储任意数量的结果。