我正在开发一个相当大的项目,我不确定当前的架构是否能胜任这项任务。我们有这样的对象:
public class Order()
{
public int id;
public int TotalProductsWeight { get; private set;}
public IList<Products> prodList = new List<Products>() { get; private set;}
public void AddProducts(IList<Products> prod)
{
prodList.AddRange(prod);
foreach(var e in prodList)
//Doing complex stuff and put the result in TotalProductWeight
}
}
有一个字段TotalProductsWeight
的计算成本很高,所以我们只在添加新产品时更新它。问题是这个对象被保存到数据库中,当我们从同一个数据库中读取它时,我们还想加载前面存储的TotalProductsweight
。
我想到的唯一解决方案是调用一个方法来更新TotalProductsWeight,忽略db上的值。
[编辑] 问题是:是否有更好的方法将复杂计算的结果存储在对象中,因此我们不需要每次重新计算它,同时只在从数据库读取时才在该字段中加载值而不暴露其余代码中的字段?
答案 0 :(得分:3)
这听起来像是懒惰评估很容易处理的东西。考虑这样的事情:
public class Order()
{
public int id;
// Cached total weight.
private int _totalProductsWeight;
// When true, must compute weight before returning
private bool _dirtyFlag;
public int TotalProductsWeight
{
get
{
if (_dirtyFlag)
{
_totalProductsWeight = ComputeWeight();
_dirtyFlag = false;
}
return _totalProductsWeight;
}
}
public IList<Products> prodList = new List<Products>() { get; private set;}
public void AddProducts(IList<Products> prod)
{
prodList.AddRange(prod);
// Mark the weight as dirty.
_dirtyFlag = true;
}
}
现在,您只需在需要时计算总重量。因此,您可以在产品列表中添加一百个项目,并且在第一次有人要求之前不必计算重量。
要存储在数据库中,您可以根据需要存储权重,并且从数据库加载时只需将脏标志设置为false。如果您不想存储总权重,请确保在加载对象的数据时将脏标志设置为true。这样,它会在第一次有人要求时计算重量。
此外,如果此信息存储在数据库中,则始终存在某人从数据库中删除产品而不更新总重量的风险。在这种情况下,如果您保留总重量并将其读回,则数据不一致。您可以自行决定是否存在应该防范的真正风险。如果你认为它可能发生,那么你可能不应该坚持总权重字段,而是在加载时(或第一次查询时)重新计算它。
请注意,执行此操作时,应该访问_totalProductsWeight
字段的唯一代码是get访问器以及将其写入数据库并将其读回的代码。如果任何其他代码读取_totalProductsWeight
,则存在读取旧值的风险。 (不是说我犯过那个错误,请注意...... 咳嗽)