大型数据集子集视图的设计模式

时间:2013-02-28 21:33:52

标签: c# .net design-patterns struct

我有一个由数千个中等大小(数百个字节)对象组成的数据结构,每个对象代表一个较大数据集的子集。由于几个原因(分析大范围时的复杂性,垃圾收集器的压力等),这不是最佳的。

从概念上讲,您可以想象代表一天的气象数据的对象,当数据集作为一个整体是一年的数据时(比方说)。琐碎的例子:

class YearData
{
   private readonly DayData[] days = new DayData[365];
   public DayData GetDayData(int dayNumber)
   {
      return days[dayNumber];
   }
}

class DayData
{
   private readonly double[] temperatures = new double[24];
   public double GetTemperature(int hour)
   {
      return temperatures[hour];
   }     
   public void SetTemperature(int hour, double temperature)
   {
      temperatures[hour] = temperature;
   }
}       

在重构工作中,我尝试将数据移动到表示整个数据集的单个对象,但为了保持其余代码不变(和简单),我需要表示数据子集/段的对象。例如:

class YearData
{
   private readonly double[] temperatures = new double[365*24];   

   public DayData GetDayData(int day)
   {
      return new DayData(this, day);
   } 

   internal double GetTemperature(int day, int hour)
   {
      return temperatures[day*24 + hour];
   }

   internal double SetTemperature(int day, int hour, double temperature)
   {
      temperatures[day*24 + hour] = temperature;
   }
}

class DayData // or struct?
{
    private readonly YearData yearData;
    private readonly int dayNumber;
    public DayData(YearData yearData, int dayNumber)
    {
       this.yearData = yearData;
       this.dayNumber = dayNumber;
    }
    public double GetTemperature(int hour)
    {
       return yearData.GetData(dayNumber, hour);
    }
    public void SetTemperature(int hour, double temperature)
    {
       yearData.SetData(dayNumber, hour, temperature);
    }
}

这样我可以拥有一个巨大且长寿的对象,并且我可以保留许多小的短期对象来分析数据。 GC更快乐,直接对整个数据集进行分析现在不那么复杂了。

我的问题是,首先:这个模式有名字吗?看起来它应该是非常常见的模式。

第二个(特定于.NET):段对象非常轻量级且不可变。这是否适合成为一个结构?其中一个struct字段是引用是否重要?对于出现可变的类型使用结构但是实际上不是吗?

是不好的形式?

2 个答案:

答案 0 :(得分:2)

非常有趣的问题和方法!

我不确定,但我认为这些模式可能会被视为FlyweightAdapter

来自Flyweightsourcemaking.com

  
      
  • 使用共享有效地支持大量细粒度对象。
  •   
  • 使用轻量级小工具替换重量级小部件的Motif GUI策略。
  •   

您持有的temperatures数组存储在YearData中,可以看作是DayData Factory。

还有Adapter

  
      
  • 将类的接口转换为客户期望的另一个接口。适配器允许类协同工作,否则   因为界面不兼容。
  •   
  • 使用新界面包装现有类。
  •   
  • 阻抗将旧组件与新系统匹配
  •   

因此,通过以这种方式公开DayData,您提供了客户想要的界面

另外,我不确定DayDate是一个结构,你可以在this answer

中查看关于何时以及如何使用结构的一个很好的解释

答案 1 :(得分:1)

Flyweight,肯定。

它允许您以最佳方式打包大数据,但仍然假装每个数据都有一个额外的对象。