我尝试将我的特定域名问题抽象到银行帐户,假设以下情况:
我将类结构设计为folows(简化):
public class Login
{
private List<Account> _bankingAccounts;
....more fields, ctor, getters, setters...
}
public class Account
{
private List<Transaction> _transactions;
....more fields, ctor, getters, setters...
}
public class Transaction
{
String _comment;
....more fields, ctor, getters, setters...
}
好吧,但是如果我说20个帐户并且每个都有10000个事务并且我从数据库加载整个模型会有大量内存,即使我不知道客户是否需要所有这些事务。
我想构建一个更简化的模型:
public class Login
{
private List<SimpleAccount> _bankingAccounts;
....more fields, ctor, getters, setters...
}
public class SimpleAccount
{
....more fields, ctor, getters, setters...
}
public class Account
{
private List<Transaction> _transactions;
....more fields, ctor, getters, setters...
}
public class Transaction
{
String _comment;
....more fields, ctor, getters, setters...
}
然后我会加载一个简化帐户(不包含所有交易)的帐户模型,只有用户请求查看特定帐户的交易我才会加载这整个帐户对象。
这样可以吗?有更好的方法吗?
答案 0 :(得分:6)
从你的问题我发现你的基本需求是ORM,因为(如果我没有错)你想要两件事
域模型映射
但是
懒惰加载
通过延迟加载我们的意思是关系对象只在我们尝试访问它们时加载。简单当你想要查看特定的学生数据时,你永远不想自动加载学生的所有课程(可能是一个集合)除非不想看他/她的课程(如果学生和课程有关系)
所以对于你的问题你应该使用ORM,它将为你提供两种解决方案:)
这是.Net
答案 1 :(得分:2)
构建域模型时,不应考虑性能影响,因为域模型是您的域,而不一定是您实现的域。
此外,如果您使用任何体面的ORM框架(例如,entity-framework),您只能从数据库加载所需的数据,而不是整个对象图。
答案 2 :(得分:1)
正如Serg所说,绩效思想属于实施,而不是域模型。
如果你想避免加载整个帐户,你应该实现某种延迟加载,例如:
public class Account
{
private List<Transaction> _transactions;
public List<Transaction> getTransactions() {
if(_transactions == null) {
loadTransactions();
}
return _transactions;
}
}
答案 3 :(得分:0)
有一种称为事件采购的模式听起来可能会对你有所帮助。它依赖于事件的存储(在您的情况下这些是事务)而不是运行总计,因此您可以对数据做更多的事情。
此模式遇到了您遇到的同样问题。所以这个模式中还增加了一个名为Snapshots的模式。在每个月末,拍摄快照可以让您获取时间点并将交易记录加载回最近的快照。快照将显示帐户在快照点处的原样(可能是上次快照或帐户开立事件的产品,其间重放了所有事务)。
如果您使用谷歌的“事件采购快照”,那么有很多文章讨论这种模式。希望这会有所帮助。