如何实现单例模式(语法) [英] How to implement Singleton Pattern (syntax)

查看:89
本文介绍了如何实现单例模式(语法)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个数据缓存,该数据正从外部来源刷新,并且我想限制对他在我的应用程序内部的缓存(只读)的访问.我不想每次需要访问数据源时都要刷新数据源(即在实例化时提取并提取所需的所有数据,因为有很多数据正在更新).

I have a cache of data which is getting refreshed from an outside source, and I want to limit my access tot his cache (readonly) inside of my app. I don't want to have refresh the datasource everytime I need access to it (ie. on instantiation go and pull all the data I need, as there is quite a bit of data that is being kept up to date).

type MySingleton = 

        [<DefaultValue>]
        static val mutable private instance: MySingleton

        static member GetInstance() = 
            instance

我想这是实现项目并尝试同时学习语言的陷阱之一.我知道逻辑需要

I guess this is one of the gotchas about implementing a project and trying to learn the language at the same time. I know the logic needs to be

if instance is null
    synchronize
    if instance is null
        instance = new MySingleton()

但是缺少null会让我陷入困境.我想我可以使用选项类型等,但这会让我陷入困境

but the lack of null is throwing me for a loop. I think I can use an option type etc but it is throwing me for a loop

type MySingleton = 

        [<DefaultValue>]
        static val mutable private instance: MySingleton option

        static member GetInstance() = 
            match instance with
                 | Some(i) -> i
                 | None -> 
                            *MySingleton.instance = new MySingleton()
                            MySingleton.instance*

根据编译器,逻辑是错误的...

that logic is wrong according to the compiler...

       if Helper.notExists MySingleton.instance then
            MySingleton.instance <- Some(new MySingleton())        
       MySingleton.instance 

我应该改为使用IF语句吗?在f#中是否有此语法的首选模式?

should I be using IF statements instead? Is there a prefered pattern for this syntax in f#?

推荐答案

Brian提到的Lazy类型是一个很好的起点.它允许您确保在需要该值时将运行计算,并且可以保证线程安全,这意味着该计算将仅运行一次(尽管在某些情况下,您也可以使用

The Lazy type as Brian mentioned is a good place to start with. It allows you to ensure that a computation will be run when the value is needed and it guarantees thread safety, meaning that the computation will run only once (although, in some cases, you may also use PublicationOnly option to specify that multiple threads may start to initialize cache and only the first result will be used).

但是,您可能还需要一种机制来将缓存标记为无效(例如,在指定的时间之后)并强制重新初始化缓存.请注意,这实际上不是 Singleton模式.无论如何,您仍然可以使用Lazy以线程安全的方式执行此操作,但是您将需要构建如下代码:

However, you'll probably also need a mechanism for marking the cache as invalid (e.g. after some specified time) and forcing re-initialization of the cache. Note that this isn't really a Singleton pattern. Anyway, you can still do this in a thread safe way using Lazy, but you'll need to structure the code like this:

module Cache = 
  // returns a lazy value that initializes the cache when 
  // accessed for the first time (safely)
  let private createCacheInitialization() = 
    lazy( // some code to calculate cache 
          cache )
  // current cache represented as lazy value
  let mutable private currentCache = createCacheInitialization()

  // Returns the current cache
  let GetCache() = currentCache.Value
  // Reset - cache will be re-initialized next time it is accessed
  // (this doesn't actually initialize a cache - just creates a lazy value)
  let Reset() = currentCache <- createCacheInitialization()

当然,您可以将此代码转换为Cache类,该类仅使用初始化函数,并将其余代码封装为可重用的部分(例如,如果需要缓存多个值).

Of course, you could turn this code into a Cache class that takes only the initialization function and encapsulates the rest of the code into a reusable piece (if you need to cache multiple values, for example).

这篇关于如何实现单例模式(语法)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆