如果已经回答了这个问题我道歉,但我找不到任何答案.
在我最近的一个采访问题中,我被问到如何实现Lazy Loading.方案如下:
解:
Order对象将具有IList.订单存储库将有一个返回所有订单的方法(为了更快,它不会返回每个订单的所有订单项,因此它将为null).
问题是"如何为Order对象进行延迟加载.即有一个Order对象,网站调用myOrder.LineItems.
我的第一个想法是Order对象将调用Order Service来获取lineitems,但这不是好的设计,因为Objects需要知道该服务,并且服务需要知道对象.当然,网站可以调用订单服务传递订单/订单ID来获取线条,但是我们怎么能让那个位看不见呢?所以Order对象包含它的所有数据,但有些只是在需要的时候加载?
谢谢,希望一切都有意义.
乔恩
作为面试官,我会在答案中寻找三件事.
这就是我回答这个问题的方法.
延迟加载由NHibernate或Entity Framework等ORM框架实现的通用功能.我的第一次尝试是使用其中一个框架(第1点)
如果ORM框架是不可能的,我将使用拦截框架(如Castle Interception或Unity Interception)实现延迟加载.(第2点).
要从头开始实现延迟加载,我将使用Decorator模式(奖励点),继承Order类并在那里定义延迟加载行为.这是设计显示相关属性:
class Order {
public int ID {get;set;}
public virtual IList<OrderLine> Lines{get;set;}
}
interface IOrderRepository {
Order GetOrder(id);
IList<OrderLine> GetOrderLines(Order order);
}
class OrderService {
IOrderRepository _repository;
public OrderService(IOrderRepository repository) {
_repository = repository;
}
public Order GetOrder(int id) {
return new OrderDecorator(_repository.GetOrder(id));
}
}
public class OrderDecorator : Order {
public OrderDecorator (IOrderRepository repository) {
_OrderLines = new Lazy<IList<OrderLine>>(()=>repository.GetOrderLines(this));
}
Lazy<IList<OrderLine>> _OrderLines;
public override IList<OrderLine> Lines {
get {
if (base.OrderLines == null)
base.OrderLines = _OrderLines.Value;
return base.OrderLines;
}
set {base.OrderLines=value;}
}
}
Run Code Online (Sandbox Code Playgroud)
这是没有Lazy<>
幻想的版本.编辑后确保代码严格符合装饰器模式,懒惰版本实际上并没有添加任何东西,所以我只是使用下面的版本.
public class OrderDecorator : Order {
public OrderDecorator (IOrderRepository repository) {
_Repo = repository;
}
IOrderRepository _Repo;
public override IList<OrderLine> Lines {
get {
if (base.OrderLines == null)
base.OrderLines = repository.GetOrderLines(this);
return base.OrderLines;
}
set {base.OrderLines=value;}
}
}
Run Code Online (Sandbox Code Playgroud)
更新这是项目布局.关于将订单和存储库耦合的评论.实际情况并非如此,因为存储库与装饰器耦合,而不是订单.