加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 用于实现此类延迟加载的设计模式?

发布时间:2020-12-16 01:58:10 所属栏目:百科 来源:网络整理
导读:我有很多类实现这样的接口: public interface IProcessor{ Foo Foo { get; set; } int Process();} 我有一个生产这些产品的工厂,我不知道它们将生产多少产品.问题是,检索必要的Foo对象是昂贵的,并且在调用Process之前,该属性实际上并未在IProcessor中使用.
我有很多类实现这样的接口:

public interface IProcessor
{
    Foo Foo { get; set; }
    int Process();
}

我有一个生产这些产品的工厂,我不知道它们将生产多少产品.问题是,检索必要的Foo对象是昂贵的,并且在调用Process之前,该属性实际上并未在IProcessor中使用.

所以,如果我的工厂有这样的方法:

public IProcessor CreateProcessor(int fooId)
{
    Foo foo = this.Context.GetFoo(fooId);

    return new ImplementedProcessor { Foo = foo };
}

我每次都要打电话给GetFoo.我真正喜欢的是这样的:

public IProcessor CreateProcessor(int fooId)
{
    this.CurrentlyTrackedFooIds.Add(fooId);

    return new ImplementedProcessor { Foo = what??? };
}

我们的想法是,在ImplementedProcessor需要Foo执行其Process方法之前,它会排队fooId,以便可以像以下那样对它们进行批量检索:

this.Context.GetAllFoosAtOnceCheaply(this.CurrentlyTrackedFooIds);

是否有任何延迟加载模式可以帮助这样的事情?我完全控制整个项目,因此我不受现有IProcessor或IProcessorFactory接口的限制.我可以想办法做到这一点(可能是某种代表吗?),但是它们中没有一个看起来很干净,我想通过在项目中拥有一百万个不同的实现来避免这种事情失控.任何帮助将不胜感激!

解决方法

所以有两种类型可以让我们的生活变得非常轻松.第一个是懒惰.构造一个Lazy对象时,为它提供一个返回值的函数.然后当你要求Lazy的值时,如果它没有启动则启动该函数,如果函数未完成则等待该函数,然后返回该值.它从不调用该函数两次.如果从未询问过该值,则甚至不会关闭该功能一次.

然后我们可以创建一个Lazy对象的ConcurrentDictionary,这样我们就可以确保得到任何现有的Lazy对象.请注意,其GetOrAdd方法是可观察的原子.我们可以确定字典不会用另一个字体覆盖现有的Lazy对象;它要么返回现有的,要么设置一个新的.这意味着我们永远不会在代表相同ID的两个不同Lazy对象上调用Value.

毕竟,编码并不多:

private  ConcurrentDictionary<int,Lazy<IProcessor>> lookup =
        new ConcurrentDictionary<int,Lazy<IProcessor>>();
public IProcessor CreateProcessor(int fooId)
{
    var lazy = lookup.GetOrAdd(fooId,new Lazy<IProcessor>(Context.GetFoo));

    return new ImplementedProcessor { Foo = lazy.Value };
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读