我有一个由数千个中等大小(数百个字节)对象组成的数据结构,每个对象代表一个较大数据集的子集。由于几个原因(分析大范围时的复杂性,垃圾收集器的压力等),这不是最佳的。
从概念上讲,您可以想象代表一天的气象数据的对象,当数据集作为一个整体是一年的数据时(比方说)。琐碎的例子:
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字段是引用是否重要?对于出现可变的类型使用结构但是实际上不是吗?
是不好的形式?答案 0 :(得分:2)
非常有趣的问题和方法!
我不确定,但我认为这些模式可能会被视为Flyweight
和Adapter
。
- 使用共享有效地支持大量细粒度对象。
- 使用轻量级小工具替换重量级小部件的Motif GUI策略。
您持有的temperatures
数组存储在YearData
中,可以看作是DayData Factory。
- 将类的接口转换为客户期望的另一个接口。适配器允许类协同工作,否则 因为界面不兼容。
- 使用新界面包装现有类。
- 阻抗将旧组件与新系统匹配
因此,通过以这种方式公开DayData
,您提供了客户想要的界面
另外,我不确定DayDate是一个结构,你可以在this answer
中查看关于何时以及如何使用结构的一个很好的解释答案 1 :(得分:1)
Flyweight,肯定。
它允许您以最佳方式打包大数据,但仍然假装每个数据都有一个额外的对象。