一位开发人员和我正在交谈(轻描淡写)对象的属性的Lazy-Loading。
那么,您将如何处理IoC和SRP之后的Lazy-Loading?
你不能单元测试延迟加载的属性。他重申那句话说:“你已经为UserStatsService进行了单元测试 - 这是你的代码覆盖率。”这是一个有效的观点,但是对于“完整”的覆盖范围,该属性仍未经过测试。
设置/代码模式:
以下是一个例子。
public class User
{
public Guid UserId { get; set; }
private UserStats _userStats;
// lazy-loading of an object on an object
public UserStats UserStats
{
get
{
if (_userStats == null)
{
// ComponentsLookup is just a wrapper around IoC
// Castle/Unity/etc.
_userStats =
ComponentsLookup
.Fetch<UserStatsService>()
.GetByUserId(this.UserId);
}
return _userStats;
}
}
}
以上显示了延迟加载对象的示例。我说不要使用它,并从UI层访问任何需要该对象的UserStatsService。
编辑:下面的一个答案让我想起了延迟加载的NHibernate技巧,即虚拟化你的属性,允许NHibernate创建一个懒惰加载本身的过载。光滑,是的,但我们没有使用NHibernate。没有人真正解决Lazy-Loading的问题。一些好文章和SO问题接近:
我确实看到了延迟加载的好处。不要弄错我,我所做的只是懒惰加载我的复杂类型及其子类型,直到我切换到忍者的D.I.-方式。好处在于UI层,其中用户的统计数据显示在具有100行的列表中。但是使用DI,现在你必须引用几行代码来获取用户统计信息(不违反SRP并且不违反Demeter法则),并且必须走这条长路径的查找次数100次。 / p>
是的,添加缓存并确保对UserStatsService进行编码以用作Singleton模式,从而大大降低了性能成本。
但是我想知道是否有其他人有一个[顽固]开发人员不会屈服于IoC和D.I.完全规则,并具有有效的性能/编码点来证明解决方法的合理性。
答案 0 :(得分:5)
实体本身不应该负责延迟加载。这是一个基础设施问题,其解决方案将在其他地方。
假设一个实体在两个不同的上下文中使用。首先,它的孩子们被大量使用并且急切地负担。在第二种情况下,它们很少使用并且是懒惰的。这也是实体关注的问题吗?配置会是什么样的?
NHibernate通过代理实体类型来回答这些问题。属性IList<Entity>
的属性由基础结构设置为知道延迟加载的实现。该实体仍然没有意识到。也会处理父引用(如您的问题),只需要一个简单的属性。
现在关注点在实体之外,基础架构(ORM)负责确定上下文和配置(如急切/延迟加载)。