【问题标题】:Auto generate unique IDs using the singleton pattern使用单例模式自动生成唯一 ID
【发布时间】:2014-12-27 13:58:03
【问题描述】:

我展示的一小段代码是用 C# 编写的,但问题更多是关于理论和设计(我认为)而不是代码本身。

在我的应用程序中,用户可以添加项目(假设它是一个愿望清单管理器,用户可以添加他的愿望)。我需要为此条目自动生成 ID。 他们给了我们一个关于如何做到这一点的例子,我们必须使用它(从我在这里读到的内容来看,GUID 是一种很好的方法,如果选择是我的,我会这样做,但是这个在这里无关紧要)。

给定的例子:

class IDGenerator
{
    private static IDGenerator instance;

    private int nextID;

    private IDGenerator() { nextID = 1; }

    [MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.Synchronized)]
    public static IDGenerator getGenerator()
    {
        if (instance == null)
        {
            instance = new IDGenerator();
        }
        return instance;
    }

    public int nextId()
    {
        return nextID++;
    }
}

然后,老师有一个Wish继承的IdObject类,每次创建一个新的Wish实例时,都会使用上面的IdGenerator生成一个唯一的ID。很简单。它基本上就像一个全局变量的包装器。

我对此有一些问题:ID 不可重用(不是什么大问题),如果我想要另一个扩展 IdObject 的类,我需要另一个 id 生成器(只需复制粘贴代码即可完成,或者我可以忍受我到处都有身份证的事实。

但我遇到的最大问题是:如果我保存愿望清单(简单的文本文件,序列化,没关系),我可能会得到重复的 ID。我可以通过在每次程序启动时强制读取文件来解决此问题,检查 ID,然后使用超出已使用 ID 范围的值初始化第一个下一个 ID,然后在每次添加项目时强制保存文件。或者我可以继续生成 ID,直到生成有效的 ID。但我不想这样做。一定有更好的方法。

那么,通过仍然使用单例模式而不是像我上面描述的那样做“魔术技巧”来做到这一点有什么好的方法吗?

【问题讨论】:

  • 我不确定我是否理解您的问题。为了避免 id 重复,您唯一需要的是一种保存生成器到目前为止分配的最后一个 id 的方法。然后每次恢复生成器时,它都必须读取保存的值,将其加 1,然后从那里继续。
  • @Leandro Caniglia 这就是我现在正在做的事情,但我认为这不是正确的方式。

标签: oop design-patterns singleton


【解决方案1】:

好的。所以问题是我如何确保IDGenerator 不会在每次恢复时一遍又一遍地重复初始序列,对吗?正如您所指出的,一种解决方案是使用足够强大的随机生成器;另一个需要保持其状态。

那么问题就变成了:persist or randomize,难道没有其他解决方案?答案是肯定的。

例如,每次您恢复生成器时,您都可以将其nextId 变量初始化为以秒表示的当前时间戳(我认为不需要毫秒。)这样就不会有任何重复。当然,您会在会话之间留下很大的未使用 id 间隔,但这可以看作是价格,如果您想让生成器的代码尽可能简单,您会很乐意支付。 p>

【讨论】:

    【解决方案2】:
       public sealed class SingletonIdGenerator
    {
        private static long _id;
        private SingletonIdGenerator()
        {
        }
    
        public string Id
        {
            get { return _id++.ToString().Substring(8); }
        }
    
        public static SingletonIdGenerator Instance { get { return Nested.instance; } }
    
        private class Nested
        {
            static Nested()
            {
                _id = DateTime.Now.Ticks;
            }
            internal static readonly SingletonIdGenerator instance = new SingletonIdGenerator();
        }
    }
    

    【讨论】:

    • 一些解释此代码的作用以及它解决问题的原因将不胜感激。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-26
    • 2016-09-27
    • 1970-01-01
    • 1970-01-01
    • 2012-02-22
    相关资源
    最近更新 更多